OD322 unknown-selection-value¶
A data record gives a Selection field a value it does not list.
| Category | Severity | Series | Needs the index |
|---|---|---|---|
| Correctness | Error | all | yes |
What it reports¶
The text of a <field>, a whole string eval, or a CSV cell, written to a Selection field, when no
definition of that field in any indexed module lists the value in a literal selection or
selection_add. A field of an _inherits parent counts as a field of the child, unless the child
has its own.
The value is compared as written, spaces included, because Odoo does not trim it either. A CSV cell also passes as a label, since the import looks both up, and from saas~14.3 as a value or label in another case. In an unknown series, any case passes.
Why it matters¶
Odoo validates the value on write, so an XML file raises ValueError: Wrong value for ..., and the
import refuses a CSV cell with Value '%s' not found in selection field. Either stops the install
or the update of the module. A demo file differs: see load
failures. The usual causes are a value
renamed in Python and missed in the data, a typo, and a label written where the value belongs.
The union over every indexed module is deliberate. A value another module adds with selection_add
loads first when that module is auto-installed, so only a value no module lists is certain to fail.
The rule stays silent where only a run tells the values:
- A selection given by a method, a lambda or a variable, or with
intkeys. - A tuple as
selectionfrom saas~17.2 up to saas~19.2, and in an unknown series. Odoo does not validate it on write there, except from saas~18.1 on a field with several definitions or one from another model, which the rule does not report either. A CSV cell still reports, since the import checks a tuple in every series. - A field with
validate=False, a related field, a field that is not stored, and a field that unpacks**kwargs. A company-dependent field counts as stored, since Odoo validates its value like a column's, unless it declaresstore=False, or acomputewithoutstore=True. - A
selection_addwhose base no indexed definition lists. - A
search, aref, atype, afile, aname@langfield, and a biggereval. Only the last<field>of a name counts. - An empty
<field>,eval="''"and an empty CSV cell. Below saas~19.3 each clears the field, unless theselectionlists''. From saas~19.3 only the CSV cell andeval="False"do: the other two write'', so Odoo raisesWrong value for ...on a literalselectionthat lacks it, and stores it on aselectiona method gives. The rule does not report that refusal. - The inverse field of a record nested in a one2many, and a record nested in any other type of field.
- A value a later write replaces in the module's scope. A value only a module outside the scope replaces still reports, since a database without that module keeps it, and so does a data value only a demo write replaces, since a database may hold no demo data.
- A file the manifest does not load.
- A module with a dependency that is not indexed, a module that builds model names at runtime, and a model with a parent the scan cannot see.
- A module with an unread data file, which may replace the value. A module that depends on one still reports, as that file has loaded by then.
Example¶
class ResPartner(models.Model):
_inherit = "res.partner"
tier = fields.Selection([("gold", "Gold"), ("silver", "Silver")])
<odoo>
<record id="partner_shop" model="res.partner">
<field name="name">Shop</field>
<field name="tier">Gold</field>
</record>
</odoo>
Gold is the label, and tier stores gold.
<odoo>
<record id="partner_shop" model="res.partner">
<field name="name">Shop</field>
<field name="tier">gold</field>
</record>
</odoo>
The value is one the field lists.