100 % of repositories · 934 findings · Technical debt
Manifest version not bumped
What happens. Breaks nothing by itself, but reveals which version the module expects and confuses whoever installs it.
How to fix it. Bump the prefix to the target version and restart the module's internal numbering.
Where I verified it. Odoo convention: the manifest declares the series the module belongs to.
55 % of repositories · 2,116 findings · Stops the module · breaks from 18.0 onwards
List views declared as <tree>
What happens. The view type no longer exists under that name; the view is not registered.
How to fix it. Rename the tag to <list> and </list>, and review any xpath pointing at //tree.
Where I verified it. In odoo 19 no file under addons/base/views uses <tree; all are <list.
50 % of repositories · 987 findings · Breaks a flow · breaks from 18.0 onwards
view_mode containing "tree" in actions
What happens. The action opens in a view mode that does not exist and the menu goes dead.
How to fix it. Change "tree" to "list" in view_mode.
Where I verified it. odoo/addons/base/views/ir_actions_views.xml:590 declares list,form.
50 % of repositories · 4,013 findings · Technical debt · breaks from 17.0 onwards
t-esc in QWeb templates
What happens. Left as debt: it works through compatibility, until it stops working.
How to fix it. Replace with t-out, which escapes the same way and also honours field widgets.
Where I verified it. QWeb documentation from 17 onwards uses t-out; t-esc remains a legacy alias.
45 % of repositories · 124 findings · Breaks a flow · breaks from 18.0 onwards
Chatter as <div class="oe_chatter">
What happens. The chatter stops rendering, or renders broken, in the form.
How to fix it. Replace the whole block with the <chatter/> tag.
Where I verified it. Form views under addons/mail in 19 use the <chatter tag.
40 % of repositories · 24 findings · Stops the module · breaks from 17.0 onwards
create() taking a single dict
What happens. Batch creation passes a list where the code expects a dict: TypeError.
How to fix it. Decorate with @api.model_create_multi and receive vals_list, iterating inside.
Where I verified it. model_create_multi is in odoo/orm/models.py and is the create contract in 19.
35 % of repositories · 5,563 findings · Stops the module · breaks from 17.0 onwards
"attrs" and "states" attributes in views
What happens. Odoo rejects the view when the module installs; the module does not start.
How to fix it. Replace with direct expressions on the field itself: invisible="condition", readonly="condition", required="condition", in Python syntax and without nested quotes.
Where I verified it. odoo/addons/base/models/ir_ui_view.py:493 raises ValidationError with the text "Since 17.0, the 'attrs' and 'states' attributes are no longer used."
30 % of repositories · 141 findings · Breaks a flow · breaks from 17.0 onwards
name_get() overridden
What happens. Nobody calls the method any more: names still display, but with the default value.
How to fix it. Rewrite as _compute_display_name assigning self.display_name, with @api.depends on the fields used.
Where I verified it. def name_get does not appear in odoo/orm/models.py in 19; _compute_display_name does.
15 % of repositories · 26 findings · Breaks a flow · breaks from 17.0 onwards
flush() on a recordset or the environment
What happens. AttributeError at runtime, usually inside a flow already in production.
How to fix it. Use flush_model() for the whole model, flush_recordset() for the set, or env.flush_all().
Where I verified it. odoo/orm/models.py exposes flush_all, flush_model, flush_query and flush_recordset.
5 % of repositories · 50 findings · Stops the module · breaks from 18.0 onwards
get_module_resource
What happens. The function no longer exists: ImportError or AttributeError when the module loads.
How to fix it. Use odoo.tools.file_path to get the path, or file_open to open the file.
Where I verified it. get_module_resource is absent from the odoo 19 tree; file_path is in odoo/tools/misc.py.
0 % of repositories · 0 findings · Stops the module · breaks from 18.0 onwards
Python modules removed in 3.12
What happens. ImportError when the module loads: those packages no longer ship with Python.
How to fix it. distutils by packaging or shutil, imp by importlib, and the rest by their standard-library replacement.
Where I verified it. The official odoo 19 image runs on Python 3.12.3.