Skip to content

OD202 model-not-in-depends

The model comes from a module missing from depends.

Category Severity Series Needs the index
Correctness Error all yes

What it reports

A model named where Odoo needs it to exist (a parent in _inherit, the comodel of a relational field, the model of a view or of a <record>, the res_model of a window action, the model a data CSV is named after) that only modules outside the module's dependencies define. The dependencies are those in depends, the modules they depend on in turn, and base. A module that Odoo always installs with base, such as web, counts as in depends. A model no indexed module defines at all is OD201 instead.

The rule stays silent on a model that a dependency that is not indexed, such as an Enterprise module, could load. A model the module defines whole is in scope, so the rule never reports one. Add the checkout of the dependency that is not indexed to --addons-path to check the other models.

A model the module may build itself gets no finding. That is a name that fits an expression code outside tests/ builds _name from, where an expression that shows no literal start fits every name, as does a parent a class in a file that does not parse does not spell out, or the name a class may take in a module of unknown series, as Series describes.

Why it matters

Odoo loads modules in dependency order and builds each module's models on top of the models already loaded. A module missing from depends may not be installed, or may load after this one. Then an _inherit on its model raises TypeError and the install fails, as a relational field does from saas~18.2, and before that such a field points at a placeholder model. A view, record or window action on the model fails when its file loads. That aborts the install when the file is a data file, or a demo file before saas~11.5. From saas~11.5 Odoo logs a warning instead and installs the module without its demo data. The module works in a database where the other one happens to be installed and loaded first, and breaks on a fresh database or when the load order changes.

Example

__manifest__.py
"depends": ["sale"],
models/sale_order.py
class SaleOrder(models.Model):
    _inherit = "sale.order"

    project_id = fields.Many2one("project.project")

project.project comes from project, which sale does not depend on.

__manifest__.py
"depends": ["sale", "project"],

Suppressing

project_id = fields.Many2one("project.project")  # odooscan: ignore[OD202]

For a data CSV, where a comment would break the file, pass --ignore OD202 or add it to ignore in the configuration file.

See suppressing a finding.