Technical guide · Real errors with message and fix

Common errors migrating Odoo 17/18 to 19

Migrating from Odoo 17 or 18 to 19 isn't a one-click job. Here are the failures that actually show up — removed APIs, broken custom modules, data integrity issues and view changes — with the error message and how to fix it.

Before you start: the rule that breaks almost every migration

Odoo doesn't support version-skipping. The migration is sequential: 17 to 18, and 18 to 19. Both the official upgrade.odoo.com service and OpenUpgrade (the OCA's free tool) work step by step. If you load a 17 dump onto a 19 server and run -u all, modules end up stuck in a to upgrade state without actually migrating, and the data gets corrupted.

The second rule: always work on a copy. Restore the backup to a test database, migrate there, validate, and only then plan the real one. A trial migration is also the only honest way to estimate the effort your custom code will take.

1. Removed APIs and attributes

attrs and states in views

This is error number one. The attrs="{...}" and states="..." attributes were removed in Odoo 17, and 19 no longer tolerates any leftover trace of them. Any inherited view that still uses them blows up when the module loads.

ParseError: Since 17.0, the "attrs" and "states" attributes are no longer used.

Fix: replace them with direct attributes invisible, readonly and required using Python expressions: invisible="state != 'draft'" instead of attrs="{'invisible': [('state','!=','draft')]}".

Removed ORM methods and fields

Methods that had been deprecated for years get removed with every major version. The typical ones: name_get() (replaced by _compute_display_name), fields_view_get() (now get_view()), and changes to the signatures of _default_get or onchange methods.

AttributeError: 'res.partner' object has no attribute 'name_get'

Fix: review the release notes and the deprecation commit for each version. OpenUpgrade documents model changes in its scripts folder, but your own code that calls those methods has to be adapted by hand — there's no automated way to do it.

Assets and JavaScript (OWL)

Since Odoo 17 the frontend is pure OWL and the assets system uses JS module imports (/** @odoo-module **/) instead of odoo.define. An old widget that still uses the old pattern or calls require('web.core') stops loading and the view is left blank.

UncaughtPromiseError: Failed to load resource / Cannot read properties of undefined

Fix: rewrite the component with the OWL API, declare the assets in web.assets_backend in the manifest and remove any odoo.define. This is by far the most expensive part to migrate if you have a lot of custom UI.

2. Custom and third-party modules that won't install

OCA dependencies without a 19.0 branch

If your module's manifest declares a depends on an OCA addon (for example queue_job, web_responsive or some account_* module) that doesn't have a published 19.0 branch yet, the install stops dead. 19 is recent, and many OCA repos take months to be ported.

odoo.exceptions.ValidationError: Unable to install module "X" because an external dependency is not met

Fix: before migrating, take inventory of all your depends and check on GitHub whether a 19.0 branch exists. If it doesn't, you have three options: wait for the port, port it yourself (and contribute it back), or drop the dependency. This is what surprises people coming from a standard Enterprise setup the most.

Manifest version and modules that won't update

Forgetting to bump the version key in the manifest to 19.0.x.y.z makes Odoo assume the module hasn't changed and skip the migration scripts. The module "installs" but the data is left half-updated, which is more dangerous than a visible error.

Fix: start the module's version number with the Odoo version (19.0.1.0.0), bump the suffix on every change that ships a migration script, and check the logs for a Loading migration script line.

3. Data integrity

Data problems are the most silent ones and the ones that cause the most pain in production. They show up when the "old" database has records that 19 no longer allows, or when a field changes type or becomes mandatory between versions.

How to avoid it: clean the data in the source version (not the migrated one), and after each jump validate with control queries: number of accounting entries, sum of debits and credits, total open orders, stock valuation. If a number doesn't add up, don't move forward until you understand why.

4. View and interface changes

Even when the module installs fine, the interface can end up broken because the structure of the standard views changed and your inheritances can no longer find the node they're looking for with XPath.

XPath that can't find the element

Element '<xpath expr="//field[@name='...']">' cannot be located in parent view

Fix: the field was moved, renamed, or the form got reorganized. Open the standard view for 19, find the new node and adjust the XPath. Using fragile selectors (exact position) is what causes these failures; it's better to anchor to stable field names.

OpenUpgrade or Odoo's official service?

There's no single answer. Here's the honest breakdown of each path, including the OCA's free option:

Criterion upgrade.odoo.com (official) OpenUpgrade (OCA, free)
Cost Included with Enterprise / Odoo.sh; paid for Community without a contract. Free and open source (AGPL/LGPL depending on the repo).
Standard data Very reliable, automated, supported by Odoo. Reliable, but you run the server and the process yourself.
Custom modules Doesn't migrate them: tells you to adapt them yourself. Same: you have to write your own migration scripts.
Control and traceability Partly a black box; you get the result. Full control: you see every script that runs.
Availability for 19.0 Available for supported versions. Depends on how mature the 19.0 branch is; check before you rely on it.

In both cases, the bulk of the work (and the real cost) is in adapting your own code and validating the data, not in running the tool. Anyone who promises an "automatic" migration for an installation with custom modules isn't being honest.

Minimum checklist before migrating to Odoo 19

Odoo 19 migration done by engineers

At FlexigoTech (Barcelona) we run the migration jump by jump, adapt your custom modules and validate data integrity. No middlemen, and a quote based on a real trial migration, not a promise.

See our migration and custom development service

FAQ

Can you jump straight from Odoo 17 to 19?

Not in a supported way. Migration is sequential: 17 → 18 → 19. Loading a 17 dump onto a 19 server leaves modules stuck in a "to upgrade" state that never actually updates and breaks data integrity. You have to chain each jump and validate between them.

Why does my custom module no longer install?

The usual reasons: removed view attributes (attrs/states), retired ORM methods (name_get), old JS assets (odoo.define instead of OWL) and OCA dependencies without a 19.0 branch. It typically fails with a ParseError, KeyError or an external dependency ValidationError.

OpenUpgrade or Odoo's official service?

If you're on Online/Odoo.sh with standard modules, the official upgrade is the most convenient and supported option. If you're self-hosting Community or have custom code, OpenUpgrade from the OCA is free and open but requires writing your own scripts. Neither migrates your custom logic automatically.

How long does it take and how much does it cost?

It depends on how many custom modules you have and how clean the data is. A standard database migrates in days; one with many custom addons can take weeks. The cost is in reviewing and rewriting your own code. The honest approach is to run a trial migration first to estimate it.

Next step

Odoo 19 migration service Talk to an engineer