OD303 duplicate-xmlid¶
The same XML id is defined twice in one file, with another model or overwriting a field.
| Category | Severity | Series | Needs the index |
|---|---|---|---|
| Correctness | Warning | all | no |
What it reports¶
An XML id that an earlier element of the same data file already defines, when the later definition:
- has another model than the first, so it cannot update that record;
- is a
<template>, a<menuitem>or any other tag that stands for a record; - is a
<record>, or a CSV row, that writes a field an earlier definition of the id in the file writes, whatever else it adds.
Records nested in a One2many field count, since Odoo gives them their own ids. The rule compares ids within one file; OD323 compares the files of a module.
Why it matters¶
Among definitions of one model, Odoo does not complain. The later definition finds the record the first one created and writes only the fields it names, so a field both name ends up with the later value and the earlier one is gone with no message. The file yields one record where its author may have meant two, with the fields of both definitions mixed, and anything that referred to the first one now points at a record that has changed under it. The usual cause is a copied block whose id was not renamed.
The rule does not compare values, so a field repeated unchanged is reported too. Rename one definition when both records are meant to exist. Otherwise drop the repeated field, or the whole copy when it writes nothing else.
An id repeated with another model cannot update the first record. That is the clash
OD323 covers: on install Odoo refuses it with a ValidationError from
saas~15.2, and that page says what earlier series do.
One rewritten field is enough here, where OD323 stays silent on a definition that adds one field and
changes another: a later file can read as a deliberate update, while a repeat within one file is far
more likely a copy. For the same reason forcecreate false, which silences OD323, changes nothing
here.
The rule stays silent on what reads as a second phase of the same record:
- A
<record>of the same model that writes only fields no earlier definition in the file writes, or writes nothing at all. - A field written with x2many commands that keep the other rows, and a field holding nested records: both add to what the field holds.
- A
<record>of the same model after a tag, unless a<record>before the tag writes the same field. Through 10.0 a<report>writesir.actions.report.xml, so a<record>of that model counts as the same model. - An id a
<function model="ir.model.data" name="_update_xmlids">call assigns: it is no definition, and a record that later sets the id is meant to update the record.
Example¶
<record id="tag_wholesale" model="res.partner.category">
<field name="name">Wholesale</field>
</record>
<record id="tag_wholesale" model="res.partner.category">
<field name="name">Retail</field>
</record>
The second record renames the first, and the database ends up with a single tag called Retail.
<record id="tag_wholesale" model="res.partner.category">
<field name="name">Wholesale</field>
</record>
<record id="tag_retail" model="res.partner.category">
<field name="name">Retail</field>
</record>
Writing a record in two steps is not a clash. A definition that names a field the first one left out updates the record and loses nothing:
<record id="tag_wholesale" model="res.partner.category">
<field name="name">Wholesale</field>
</record>
<record id="tag_wholesale" model="res.partner.category">
<field name="color" eval="3"/>
</record>