Skip to content

OD219 tracking-without-mail-thread

A field sets tracking on a model that does not inherit mail.thread, which Odoo ignores.

Category Severity Series Needs the index
Correctness Warning 14.0 and later yes

What it reports

A field definition that gives tracking, whatever its value, on a model that does not inherit mail.thread: no class of the model or of the models it inherits defines _valid_field_parameter. A field is reported once per module, at the tracking of its last definition in the module that gives it.

Why it matters

A field does not know the tracking attribute itself. When Odoo sets up the registry, it asks the model's _valid_field_parameter about each attribute a field does not know, and BaseModel accepts none but related_sudo. mail.thread accepts tracking, from saas~19.3 through the mail.track.mixin it inherits; any other model logs a warning that the parameter is unknown, and no change of the field is ever posted in a chatter. tracking=False is reported too: Odoo refuses the attribute whatever its value. Inherit mail.thread, with mail in depends, or remove tracking.

Before 14.0, Odoo ignores tracking on such a model and logs nothing, and the rule does not run.

Any class of the model or of a model it inherits that defines _valid_field_parameter silences the rule, since it may accept tracking, in whichever indexed module it is. A class of base does not: the override mail adds to base accepts tracking only on abstract models, and only before saas~19.3. So an abstract model is not reported before saas~19.3, and is from saas~19.3, where Odoo does not accept tracking on it.

The rule does not run for a module when the module or one of its dependencies depends on a module that is not indexed. A model is skipped when the class that introduces it, with _name or as a class Odoo names, is in a module outside the dependencies, or when a class of it, or of a model it inherits or delegates to, has a plain Python base class or an _inherit element that is not a literal, a parent whose methods the scan cannot see. A module that Odoo always installs with base, such as web, counts as in depends.

Example

models/parcel_crate.py
class ParcelCrate(models.Model):
    _name = "parcel.crate"
    _description = "Parcel crate"

    state = fields.Selection([("open", "Open"), ("sealed", "Sealed")], tracking=True)
models/parcel_crate.py
class ParcelCrate(models.Model):
    _name = "parcel.crate"
    _description = "Parcel crate"
    _inherit = ["mail.thread"]

    state = fields.Selection([("open", "Open"), ("sealed", "Sealed")], tracking=True)

Suppressing

state = fields.Selection([("open", "Open")], tracking=True)  # odooscan: ignore[OD219]

See suppressing a finding.