Technical guide · Real errors with message and fix

Common Odoo 19 Migration Errors

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 problems 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 skipping versions. Migration is sequential: 17 to 18, then 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 get stuck in to upgrade state without actually migrating, and data gets corrupted.

The second rule: always work on a copy. Restore the backup into 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 of your custom code.

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 usage. Any inherited view that still uses them breaks the module on load.

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')]}".

Retired ORM methods and fields

Methods that had been deprecated for years get removed on every major version. Typical examples: name_get() (replaced by _compute_display_name), fields_view_get() (now get_view()), and changed signatures on _default_get or onchange methods.

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

Fix: review the release notes and deprecation commits for each version. OpenUpgrade documents model changes in its scripts folder, but the custom code that calls those methods still has to be adapted by hand: there's no automation that does it for you.

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 previous 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 the manifest's web.assets_backend and remove any odoo.define. This is usually 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 yet have a published 19.0 branch, installation stops dead. Odoo 19 is recent and many OCA repos take months to port over.

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

Fix: before migrating, take inventory of all your depends entries 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 most surprises people coming from a standard Enterprise setup.

Manifest version and modules that "won't update"

Forgetting to bump the manifest's version key to 19.0.x.y.z makes Odoo think the module hasn't changed, so it skips 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 Loading migration script.

3. Data integrity

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

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

4. View and interface changes

Even when the module installs, the interface can end up broken because the structure of standard views changed and your inheritances no longer find the node they're targeting 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 was reorganized. Open the standard view in 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 free OCA 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 Not migrated: you're told to adapt them yourself. Same here: you have to write your own migration scripts.
Control and traceability Partially a black box; you receive 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 relying 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 promising 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 migrate hop by hop, adapt your custom modules and validate data integrity. No middlemen, and a quote based on a real trial migration, not a promise.

See the 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 hop and validate between them.

Why does my custom module no longer install?

The usual causes: 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 usually fails with a ParseError, KeyError, or a ValidationError about an external dependency.

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 run self-hosted Community or custom code, the OCA's OpenUpgrade is free but requires you to write your own scripts. Neither migrates your custom logic automatically.

How long does it take and what does it cost?

It depends on how many custom modules you have and how clean the data is. A standard database can be migrated 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 Coming from Sage? Check the migration module