UPGRADE

The Odoo upgrade broke our customisations.

It's the most common Odoo complaint there is, and it's structural rather than bad luck. Odoo ships a major version every year and refactors core internals as it goes — fields change, methods get renamed, view inheritance shifts, the JavaScript framework gets replaced. Custom modules written against the old internals don't reliably survive that, and Odoo's own Upgrade Service explicitly doesn't convert them.

The bad news is there's no trick that makes this go away. The good news is most of the damage comes from a small number of avoidable patterns, and the recovery order matters more than people think.

Cause

Why this happens

Odoo's Upgrade Service converts standard modules, database structures and Studio customisations. Odoo's documentation states plainly that it does not upgrade the source code of custom modules or third-party apps — and that a database containing custom modules cannot be upgraded until compatible versions of those modules exist.

It also puts validation squarely on you: verifying the upgraded database, detecting bugs and analysing the impact of changes is the customer's responsibility per the Enterprise Subscription Agreement.

So when an upgrade "breaks things," what happened is usually one of:

  • A field or method a custom module depended on was renamed or removed
  • A view your module inherited from was restructured, so the XPath no longer matches
  • A core method your module overrode changed signature or behaviour
  • Frontend code written against the old JS framework no longer loads
  • A third-party app hasn't released a compatible version, so it simply isn't there

The dangerous ones fail quietly. A module that crashes on install gets fixed on day one. A module that silently stops writing one field, or applies a discount rule that no longer fires, surfaces three weeks later in the accounts.

Recovery

What to do first, in order

1. Stop and inventory before fixing anything. The instinct is to fix the loudest breakage. Resist it for an hour. List every custom and third-party module, who uses it, and what it touches. You're about to make triage decisions and you need the map.

2. Separate "broken" from "gone." A module that errors is visible. A module that didn't install at all is invisible, and the workflow it powered just isn't happening. Check the installed module list against your inventory — that comparison finds the silent ones.

3. Check the quiet paths. Scheduled actions, automated rules, email templates, report layouts, webhooks and API integrations. None of these announce themselves on a screen, and all of them break the same way.

4. Reconcile numbers, not just screens. Run the same report for a pre-upgrade period on both versions. If a total moved, a computation changed, and that's worth more than any amount of clicking around.

5. Triage ruthlessly. For each broken module, ask whether anyone still uses it. Long-running Odoo instances carry modules built for processes that changed years ago. Deleting one is free; fixing it isn't. This routinely removes a third of the work and it's the highest-value hour in the whole exercise.

6. Then fix, in business-impact order. Things that stop you invoicing or shipping first. Cosmetic last.

Next time

What should have happened, for next time

Not a reprimand — this is the checklist for version 20.

Upgrade a test copy first, always. Odoo provides upgraded test databases for exactly this. Nothing should reach production before someone has spent a day using a converted copy.

Time it deliberately. Upgrade scripts can take three to four months after a major release to be production-ready, and waiting around six months lets the early stability patches land. Going first means finding the bugs on behalf of everyone else.

Don't skip versions. 14 → 19 is harder than three sequential upgrades, not easier. And staying put now has its own price: Odoo reportedly applies a 25% subscription surcharge from April 2026 for versions more than three releases behind.

Write down the test plan. The twenty things your business must be able to do. Order-to-cash, procure-to-pay, month-end. Run them on the test copy. This is the artifact that turns "it seems fine" into an actual check, and it gets reused every year.

Budget the validation, not just the conversion. One published quote for a 24-user database with minimal customisation came to 272 hours. The hours aren't in the conversion. What an Odoo upgrade costs breaks that down.

Prevention

How to have less of this next time

The bill is a function of how much custom code you carry. Four things genuinely reduce it:

Delete what nobody uses. Do the audit annually, not at upgrade time under pressure.

Prefer configuration to code. Anything achieved with configuration is free at upgrade. Anything achieved with a module is an annual instalment.

Write modules that extend rather than override. A module that adds a field and inherits a view ports in hours. One that monkey-patches core methods is a rewrite every year. If you're commissioning custom work, this is a legitimate thing to specify.

On Enterprise, weigh Studio properly. Studio customisations are covered by the Upgrade Service where custom modules aren't. That coverage is a real part of what the Custom plan buys and it's rarely counted when people compare tiers.

Odin

The structural version of the problem

Most businesses reach this page because they have custom modules somebody wrote once and nobody has touched since. The original developer has moved on. The code isn't documented. Nobody's certain what half of it does, which makes deleting it feel risky and fixing it expensive.

That's not really an upgrade problem. It's a maintenance-ownership problem that upgrades expose once a year.

Our approach is to make regenerating a module cheaper than repairing one. Changes are described in plain English to our AI builder, which writes an ordinary Odoo module onto your test copy first — so when a new version arrives, a module that no longer fits is a description away from being rebuilt against the new internals rather than a quote away from being repaired. And because the output is standard readable Odoo code, a developer can take any of it over, and it leaves with you if you go. See building Odoo modules without a developer.

Version upgrades themselves are included in the monthly fee — $150/month for up to 25 people, $450/month unlimited — run on a test copy first, so the annual upgrade is a scheduled event rather than a project nobody budgeted for.

What that doesn't remove: somebody still has to confirm the business works afterwards. No hosting arrangement, ours included, makes validation disappear. It just moves it before go-live instead of after.

See the pricing · Flat-fee Odoo hosting

Questions

FAQ

Why did the Odoo upgrade break my custom modules?

Odoo refactors core internals between major versions — renamed fields and methods, restructured views, a replaced JavaScript framework. Custom modules written against the old internals stop matching, and Odoo's Upgrade Service doesn't convert custom code.

Does Odoo fix custom modules during an upgrade?

No. The Upgrade Service covers standard modules, data structures and Studio customisations, plus custom modules under a paid maintenance-of-customisations contract. Everything else is yours.

How do I find out what actually broke?

Compare the installed module list against your inventory to find modules that didn't install at all, then check scheduled actions, automated rules, email templates, reports and integrations. Finally, reconcile a pre-upgrade report period across both versions.

Can I roll back an Odoo upgrade?

Only by restoring a pre-upgrade backup, which means losing anything entered since. This is why upgrading a test copy first matters more than any other single practice.

How long should I wait before upgrading Odoo?

Around six months after a major release is a common recommendation. Upgrade scripts can take three to four months to be production-ready, and early patches fix the worst issues.

Should I skip versions to save money?

No. Multi-version jumps are harder than sequential ones, and there's a reported 25% subscription surcharge from April 2026 for running more than three releases behind.

How do I stop this happening every year?

Carry less custom code. Audit and delete unused modules annually, prefer configuration over development, and specify that custom work extends rather than overrides core.

Upgrades on a test copy first. Included, not quoted.

$150/month up to 25 people.