Odoo upgrade error

ir_model_data_name_nospaces check constraint violation

Last updated: October 2026

A custom field with a space in its technical name breaks the upgrade when Odoo creates its external ID.

This page is part of our guide on how to upgrade Odoo Community Edition. It explains what triggers the error, how to fix it by hand, and what an automated migration does about it.

The error

psycopg2.errors.CheckViolation: new row for relation "ir_model_data" violates check constraint "ir_model_data_name_nospaces"

The DETAIL line that follows shows the failing row, with an external ID such as field_hr_employee__x_Private mobile. Through the ORM the same constraint reads "External IDs cannot contain spaces".

Constraint
CHECK(name NOT LIKE '% %') on ir_model_data, present in Odoo 15 to 19
Upgrade hops
Any; first seen on 15→16
Seen when
A module with the bad field is loaded during -u all

When you see it

During an update Odoo reflects every field into ir_model_fields and makes sure each one has an external ID named field_<model>__<field>. Missing IDs are inserted in one batch per module. If one field name contains a space, its external ID contains a space too, the check constraint rejects the row and the whole batch fails. The module load stops and the upgrade with it.

The field can sit in the old database for years without trouble, because the constraint only fires when the external ID is created. That happens when the ID was never there or was removed, for example by a database clean-up app that prunes ir_model_data.

Root cause

Odoo's own field form rejects such names with "Field names can only contain characters, digits and underscores (up to 63)." Fields like x_Private mobile or x_Graduation year come from apps that write to ir_model_fields directly, typically dynamic custom-field builders, or from scripts. The column exists in PostgreSQL with the quoted name, and Odoo can even read and write it, which is why nobody notices.

List the affected fields:

SELECT id, model, name
FROM ir_model_fields
WHERE name ~ '[^a-zA-Z0-9_]'
ORDER BY model, name;

How to fix it

Rename each field to a valid technical name before upgrading. If the field holds no data you need, deleting it from Settings > Technical > Fields in the old version is simpler. To keep the data, rename the field and its column:

Before you change anything: Back up the database before running any UPDATE or INSERT below, and try it on a copy first. These statements change data directly, outside the Odoo ORM.

-- one field, example on hr.employee
UPDATE ir_model_fields
SET name = 'x_private_mobile'
WHERE model = 'hr.employee' AND name = 'x_Private mobile';

ALTER TABLE hr_employee RENAME COLUMN "x_Private mobile" TO x_private_mobile;

Then update everything that refers to the old name, or those places break after the rename:

  • Views: search ir_ui_view.arch_db for the old name and edit the views that use it.
  • Saved filters (ir_filters), record rules (ir_rule.domain_force), window actions (ir_act_window.domain and context) and server action code.
  • Export templates (ir_exports_line) and any related or computed field that depends on it.
  • Its external ID, if one exists: rename the matching ir_model_data row to the new field_<model>__<name> form.

Do the same for every row the SELECT returned, then run the upgrade again.

How OCU handles it

Every OCU upgrade step starts with a repair for this in the base pre-migration script. Each field whose technical name contains characters other than letters, digits and underscores is renamed: invalid characters become underscores (x_Private mobile becomes x_Private_mobile), with a numeric suffix if that name is taken. The column is renamed with it, and the references are rewritten: related and depends definitions, company-dependent values, external IDs, translations, view architecture, filters, record rules, window and server actions, automation rules and export lines.

Each field is renamed inside its own savepoint, so one field that cannot be renamed does not undo the others. The field keeps its data under the new name.

A free test migration shows whether your database runs into this or any other upgrade error before you change anything on your production server.

Frequently asked questions

Why did the database work fine before the upgrade?
The constraint only checks rows that are inserted or updated in ir_model_data. A field with a space in its name only fails once Odoo tries to create its external ID, which happens during a module update.
Will renaming the field lose data?
No. Renaming the column keeps every value. What breaks are references to the old name in views, filters and actions, so update those in the same change.
Which app creates field names with spaces?
Odoo itself does not allow them. In the cases we have seen, the fields came from a third-party dynamic custom field builder that inserts rows into ir_model_fields without Odoo's name validation.

Related

Find upgrade errors before your production run

Upload a backup and run a free test migration. You get the upgraded database, the full log and every warning, with no change to your live system.

Start your free test migration