Skip to content

OD309 unknown-record-field

A data record sets a field its model does not have.

Category Severity Series Needs the index
Correctness Error all yes

What it reports

A <field name="..."> of a <record>, or a column of a data CSV, that names no field of the record's model, or a field that only a module missing from depends adds. From saas~18.2 a name@fr style name sets a translation of name and is read as name, also when the series is unknown. Below saas~18.2 it is a name like any other. A module that Odoo always installs with base, such as web, counts as in depends.

Why it matters

Odoo creates or writes the record with the values the file gives. What it does with a <field> naming no field depends on the series. Before 13.0 create logs a warning and drops the key (9.0 openerp/models.py:4172, 12.0 odoo/models.py:3584), so the install passes without the value. write does the same before saas~12.5 (9.0 openerp/models.py:3851, 12.0 odoo/models.py:3340). On saas~12.5 it raises a KeyError (saas-12.5 odoo/models.py:3397), so a new record loads and a write to one that exists stops the load. From 13.0 both raise Invalid field 'x' and the install stops (13.0 odoo/models.py:3543,3782).

A CSV column stops the install on every series, since Odoo looks each column up before it reads a row (9.0 openerp/models.py:1140, 12.0 odoo/models.py:995). From 18.0 the message is Invalid field name 'x' (18.0 odoo/models.py:1489).

From saas~18.2 the loader skips a name@fr style name (saas-18.2 odoo/tools/convert.py:396,704, 19.0 :398,730, 20.0 :415,748) and the load of a language's terms reads it as a translation (19.0 odoo/tools/translate.py:784,815, odoo/addons/base/models/ir_module.py:996-997). Below saas~18.2 Odoo treats the name as the unknown names above, so put the translation in the module's i18n file instead. A chart template CSV under data/template is one account reads itself (17.0 addons/account/models/chart_template.py:1136,1157), and this rule reads no such file.

Below 18.0 ir.property has no field value, yet its create and write pop that name and store it in the column of the property's type (9.0 openerp/addons/base/res/ir_property.py:67,102,105, 17.0 odoo/addons/base/models/ir_property.py:79,118,139). A <record> that sets value is correct there and goes unreported, also when the series is unknown. A CSV column value stays reported, since the column lookup above comes before create: set it from a <record>, or name the typed column, such as value_text. 18.0 removes the model.

A demo file differs: see load failures. When the field comes from a module outside depends, the file loads where that module is installed. Where it is not, or where it loads after this one, the field counts as unknown, as above. Correct the name, or add the module that gives the field to depends.

A record on a model that no indexed module defines is reported once by OD201, and one on a model from a module outside depends once by OD202. Neither has its fields checked. The exception is a model that the module, or a module it depends on, extends with an _inherit class. It then counts as known, so the record gets neither code on its model, and each field the module cannot see is an OD309.

The rule stays silent for a module whose dependencies include one that is not indexed, such as an Enterprise module, which may define the model or add the field. So do OD201 and OD202 on the record's model. A class in scope in a file that does not parse counts as one the scan cannot read, so a record on its model is left alone.

A field an ir.model.fields record adds counts, as OD304 describes.

Example

data/res_partner_category_data.xml
<record id="tag_wholesale" model="res.partner.category">
    <field name="name">Wholesale</field>
    <field name="colour" eval="4"/>
</record>

The field on res.partner.category is spelled color.

data/res_partner_category_data.xml
<record id="tag_wholesale" model="res.partner.category">
    <field name="name">Wholesale</field>
    <field name="color" eval="4"/>
</record>

Suppressing

<!-- odooscan: ignore[OD309] -->

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

See suppressing a finding.