odoo/odoo · error · UserError
You cannot modify the taxes related to a posted journal item
Error message
You cannot modify the taxes related to a posted journal item, you should reset the journal entry to draft to do so.
What it means
account.move.line.write() refuses to change tax_ids or tax_line_id on a line whose parent move is in state 'posted'. Tax fields on posted entries are immutable because they affect the tax report and legal figures; you must first reset the entry to draft.
Source
Thrown at addons/account/models/account_move_line.py:1844
"You cannot edit the following fields: %(fields)s.\n"
"The following entries are already hashed:\n%(entries)s",
fields=[f['string'] for f in self.fields_get(violated_fields).values()],
entries='\n'.join(hashed_moves.mapped('name')),
))
line_to_write = self
vals = self._sanitize_vals(vals)
matching2lines = None # lazy cache
lines_to_unreconcile = self.env['account.move.line']
st_lines_to_unreconcile = self.env['account.bank.statement.line']
tax_lock_check_ids = []
for line in self:
if not any(self.env['account.move']._field_will_change(line, vals, field_name) for field_name in vals):
line_to_write -= line
continue
if line.parent_state == 'posted' and any(self.env['account.move']._field_will_change(line, vals, field_name) for field_name in ('tax_ids', 'tax_line_id')):
raise UserError(_('You cannot modify the taxes related to a posted journal item, you should reset the journal entry to draft to do so.'))
# Check the lock date.
if line.parent_state == 'posted' and any(self.env['account.move']._field_will_change(line, vals, field_name) for field_name in protected_fields['fiscal']):
line.move_id._check_fiscal_lock_dates()
# Check the tax lock date.
if line.parent_state == 'posted' and any(self.env['account.move']._field_will_change(line, vals, field_name) for field_name in protected_fields['tax']):
tax_lock_check_ids.append(line.id)
# Break the reconciliation.
if (
line.matching_number
and (changing_fields := {
field_name
for field_name in protected_fields['reconciliation']
if self.env['account.move']._field_will_change(line, vals, field_name)
})
):View on GitHub (pinned to 1e661df964)
Solutions
- Call move.button_draft() first, apply the tax change, then re-post with move.action_post().
- If the move is locked by a lock date, move the lock date or post a correcting credit note instead.
- For code paths that must not unpost, filter out posted lines and report them instead of writing (see validation snippet).
Example fix
// before
invoice.line_ids.write({'tax_ids': [(6, 0, [tax.id])]}) # UserError if posted
// after
if invoice.state == 'posted':
invoice.button_draft()
invoice.line_ids.write({'tax_ids': [(6, 0, [tax.id])]})
invoice.action_post() Defensive patterns
Strategy: validation
Validate before calling
tax_vals = {k: vals[k] for k in ('tax_ids', 'tax_line_id') if k in vals}
if tax_vals and line.parent_state == 'posted':
line.move_id.button_draft()
line.write(vals) Prevention
- Wrap any tax-editing automation in draft -> edit -> post.
- Import pipelines should filter out tax fields when the target move is posted.
- Unit-test write paths against posted moves.
When it happens
Trigger: write({'tax_ids': [...]}) or write({'tax_line_id': id}) on an account.move.line with line.parent_state == 'posted', where _field_will_change() confirms the value actually differs. Common from UI edits, API imports, or code applying a manual tax after posting.
Common situations: Fixing a wrong tax on a posted invoice from a custom script; syncing tax changes from an external system into posted Odoo entries; onchange-side effects trying to recompute tax lines while the move stays posted.
Related errors
- This entry contains taxes that are not compatible with your
- You cannot create a move already in the posted state. Please
- You can't delete a posted journal item. Don’t play games wit
- You cannot delete a tax line as it would impact the tax repo
- There is no tax cash basis journal defined for the '%s' comp
AI-assisted analysis of odoo/odoo@1e661df964 (2026-08-15).
Data as JSON: /api/errors/2c1fe7307ac2dbde.
Report an issue: GitHub.