[FIX] stock_account: skip accounts that don't exist yet in company_data - #5890
[FIX] stock_account: skip accounts that don't exist yet in company_data#5890quoc-pn wants to merge 1 commit into
Conversation
update_from_coa_generic() included a record_id in filtered_records whenever the target field appeared unset. But when ref_or_id() can't resolve the xmlid to an existing account.account record, indexing the field on the resulting empty recordset is also falsy, so a not-yet-existing account was treated the same as an existing account with the field unset. AccountChartTemplate._load_data() then created a new account.account row from only the partial company_data (the 2 stock-account fields), missing required fields like name/account_type, causing: null value in column "name" of relation "account_account" violates not-null constraint Skip record_ids that don't resolve to an existing record instead of partially-creating them.
|
@MiquelRForgeFlow Could you please review this PR? It replaces PR #5887, which was accidentally closed. Thanks! |
hbrunn
left a comment
There was a problem hiding this comment.
This is not the correct way to deal with this situation. If a record doesn't exist at this point, the COA wasn't migrated correctly. A fallback could be to actually create the record then, but again, getting there points to something going wrong before.
And I keep insisting that your PRs must conform to https://github.com/OCA/.github/blob/master/AI_POLICY.md
@hbrunn I added details about my current situation to the description. I hope this provides you with more context. |
|
@quoc-pn you should run |
@pedrobaeza Thanks for your suggestion. I'll try using |
|
Please note that I am not a code expert, but I try my best. I keep running into this error, i have spent hours trying to solve this, but my original table account_account ends at 202, there is no row 203. I have no idea where the script is pulling row 203 from. I hope this is the right place to post this. `2026-08-06 17:12:29,127 12169 INFO newdb odoo.modules.migration: module stock_account: Running upgrade [$19.0.1.1] end-migration 2026-08-06 17:12:29,909 12169 ERROR newdb OpenUpgrade: stock_account: error in migration script /opt/openupgrade19/openupgrade_scripts/scripts/stock_account/19.0.1.1/end-migration.py: null value in column "account_type" of relation "account_account" violates not-null constraint 2026-08-06 17:12:29,909 12169 ERROR newdb OpenUpgrade: null value in column "account_type" of relation "account_account" violates not-null constraint |
Follow-up to #5885, which fixed the case where a record already exists but the target field is already set. There is still a related bug for records that don't exist yet.
Problem
While testing this migration against a real customer database (from Odoo 16), I hit a crash while migrating a company using the French chart of accounts (fr chart template). The failure happens because the migration tries to attach two optional fields — account_stock_expense_id and account_stock_variation_id — onto a specific account defined by the chart template: the generic "Raw materials and supplies" account (code 310000) and its matching expense account (code 601000, "Inventory item purchases – Raw materials and supplies").
The problem: this customer's company doesn't have those two generic accounts, and never has — going all the way back to their original installation. What they have instead are more specific accounts for the same purpose, split by material category: 311000/312000/317000 (raw materials A/B/C) and 601100/601200/601700 (the matching purchase accounts). This is exactly what Odoo's own French chart template provided by default at the time this company was first set up — it wasn't a customization on their part.
Since then, the official French chart template has evolved: the older per-category accounts (311/312/317, 601.1/601.2/601.7) are no longer part of the standard template, and a single generic pair (310000/601000) was introduced in their place. For a brand-new install today, that generic account gets created as part of the normal chart-of-accounts setup. But for a company migrating from an older version, there is no equivalent account to find because the account structure itself has changed — not because anything is missing or was deleted from their data.
Bug
update_from_coa_generic()instock_account/19.0.1.1/end-migration.pybuildsfiltered_records[record_id]based on whether the target field appears unset vianot ref_or_id(record_id, model_name)[key]. Whenref_or_id()can't resolve the xmlid to an existingaccount.account(the account hasn't been created yet in this company's chart), indexing[key]on the resulting empty recordset is also falsy — so a not-yet-existing account is treated the same as an existing account with the field unset.AccountChartTemplate._load_data(company_data)then creates a newaccount.accountrow from only the partialcompany_data(just the 2 stock-account fields), missing required fields likename/account_type, causing:Suggestion
Automatically creating this account during migration would mean introducing a brand-new account into a company's live chart of accounts that they never asked for and never had — purely as a side effect of a version upgrade.
The safer path is to let the migration skip this gap entirely and complete without touching the chart of accounts. Bringing the chart of accounts up to the newer template's structure can then be handled separately.
Fix
Skip
record_ids that don't resolve to an existing record instead of partially-creating them. This script is meant to backfill fields on existing accounts, not create new ones.Test
Reproduced during a 19.0 migration where
stock_account'send-migration.pycrashed onAccountChartTemplate._load_data()with the above error even after #5885; confirmed the crash disappears with this fix applied.Assisted-by: Claude Sonnet 5