{"record":{"id":"fa47294b2f603378","repo":"odoo/odoo","slug":"you-cannot-perform-this-action-on-an-account-that","errorCode":null,"errorMessage":"You cannot perform this action on an account that contains journal items.","messagePattern":"You cannot perform this action on an account that contains journal items\\.","errorType":"exception","errorClass":"UserError","httpStatus":null,"severity":"error","filePath":"addons/account/models/account_account.py","lineNumber":1158,"sourceCode":"                ],\n                ['code_store'],\n            ):\n                duplicate_codes = duplicates.mapped('code')\n            if duplicate_codes:\n                raise ValidationError(\n                    _(\"Account codes must be unique. You can't create accounts with these duplicate codes: %s\", \", \".join(duplicate_codes))\n                )\n\n    def _load_records_write(self, values):\n        if 'prefix' in values:\n            del values['code_digits']\n            del values['prefix']\n        super()._load_records_write(values)\n\n    @api.ondelete(at_uninstall=False)\n    def _unlink_except_contains_journal_items(self):\n        if self.env['account.move.line'].sudo().search_count([('account_id', 'in', self.ids)], limit=1):\n            raise UserError(_('You cannot perform this action on an account that contains journal items.'))\n\n    @api.ondelete(at_uninstall=False)\n    def _unlink_except_linked_to_fiscal_position(self):\n        if self.env['account.fiscal.position.account'].search_count(['|', ('account_src_id', 'in', self.ids), ('account_dest_id', 'in', self.ids)], limit=1):\n            raise UserError(_('You cannot remove/deactivate the accounts \"%s\" which are set on the account mapping of a fiscal position.', ', '.join(f\"{a.code} - {a.name}\" for a in self)))\n\n    @api.ondelete(at_uninstall=False)\n    def _unlink_except_linked_to_tax_repartition_line(self):\n        if self.env['account.tax.repartition.line'].search_count([('account_id', 'in', self.ids)], limit=1):\n            raise UserError(_('You cannot remove/deactivate the accounts \"%s\" which are set on a tax repartition line.', ', '.join(f\"{a.code} - {a.name}\" for a in self)))\n\n    def action_open_related_taxes(self):\n        related_taxes_ids = self.env['account.tax'].search([\n            ('repartition_line_ids.account_id', '=', self.id),\n        ]).ids\n        return {\n            'type': 'ir.actions.act_window',\n            'name': _('Taxes'),","sourceCodeStart":1140,"sourceCodeEnd":1176,"githubUrl":"https://github.com/odoo/odoo/blob/1e661df964b1b264c9cef3ab28430d4785be3fda/addons/account/models/account_account.py#L1140-L1176","documentation":"UserError raised by the @api.ondelete(at_uninstall=False) hook _unlink_except_default() on barcodes.nomenclature when the unlink recordset includes the record referenced by the external ID barcodes.default_barcode_nomenclature. Odoo keeps this shipped nomenclature as a guaranteed default; the guard blocks its deletion during normal use but allows it at module uninstall.","triggerScenarios":"Calling unlink() on a recordset containing the default nomenclature — deleting it from the Barcode Nomenclature list view, or a server script purging all nomenclatures (e.g. env['barcodes.nomenclature'].search([]).unlink()).","commonSituations":"Data-cleanup scripts that unlink everything; admins deleting 'unused' nomenclatures; duplicated nomenclature lists where users select-all and delete.","solutions":["Exclude the default record from the delete set","If you want a different default, point the barcodes.default_barcode_nomenclature XMLID reference elsewhere (a module override) — do not just unlink it","Adjust cleanup scripts to filter by id != env.ref('barcodes.default_barcode_nomenclature').id"],"exampleFix":"# before\nenv['barcodes.nomenclature'].search([]).unlink()\n\n# after\ndefault = env.ref('barcodes.default_barcode_nomenclature', raise_if_not_found=False)\nnoms = env['barcodes.nomenclature'].search([])\n(noms - default).unlink() if default else noms.unlink()","handlingStrategy":"validation","validationCode":"default = self.env.ref('barcodes.default_barcode_nomenclature', raise_if_not_found=False)\nnoms = self.env['barcodes.nomenclature'].search([])\nif default:\n    noms -= default\nnoms.unlink()","typeGuard":null,"tryCatchPattern":"from odoo.exceptions import UserError\ntry:\n    noms.unlink()\nexcept UserError as e:\n    if 'default barcode nomenclature' in str(e):\n        # retry without the default record\n        (noms - self.env.ref('barcodes.default_barcode_nomenclature')).unlink()\n    else:\n        raise","preventionTips":["Never unlink all records of a model with an @api.ondelete guard — subtract env.ref() defaults first","Favor archiving or deactivating instead of unlinking shipped system records","Note at_uninstall=False: the guard applies during runtime, so cleanup modules must respect it too"],"tags":["odoo","barcodes","delete-guard","system-records"],"backgroundTag":null,"analyzedSha":"1e661df964b1b264c9cef3ab28430d4785be3fda","analyzedAt":"2026-08-15T05:22:16.142Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}