Skip to content

OD604 unknown-rpc-method

orm.call() names a method its model does not have.

Category Severity Series Needs the index
Correctness Error all yes

What it reports

A call orm.call(model, method, ...) with literal names, where the model exists but neither its classes, those of the models it inherits, nor BaseModel define the method, or where only a module missing from depends adds it. A module that Odoo always installs with base, such as web, counts as in depends. A method of a model reached through _inherits or delegate=True does not count, since the model gets that model's fields and not its methods. The service is recognised as for OD603. OD312 says what defines a method.

Most methods of BaseModel count on every series. Some count only on the series that has them: name_get counts through saas~17.2 and is reported after it, so call what the module's series offers. ids is reported, since it is a property and not a method, and so are concat and union where Odoo makes them private, from 16.0 but for saas~16.1 to 16.4 and saas~17.1 to 17.3. is_transient is reported from 19.0, which refuses a class method. A module of unknown series may run on any, so every such method counts.

Why it matters

The server resolves the method when the request arrives and answers with an AttributeError the user sees as a dialog, every time the call runs. A method that a module outside depends adds exists only where that module happens to be installed. The usual cause is a method renamed or removed upstream between series, or a typo.

The rule stays silent when it cannot see every class: a module whose dependencies include one that is not indexed, such as an Enterprise module, a module that builds model names at runtime, a model that is unknown or outside depends (OD603 reports those), and a class of the model, or of a model it inherits, with a plain Python base or an _inherit no indexed module defines, or in a file that does not parse, which counts as one the scan cannot read. The server finds a method of such a parent on the class, so the rule treats it as defined, and a misspelled name on such a model is not reported either. Such a class of a model reached through _inherits or delegate=True does not count, since those methods stay on that model. To have the model checked, drop the plain base from the class statement: make it an AbstractModel that only _inherit names.

The other service methods, such as searchRead() and write(), map to methods every model has, so only call() is checked.

Example

static/src/js/order_button.js
await this.orm.call("sale.order", "action_confirm_order", [[this.props.record.resId]]);

sale.order has no action_confirm_order: the method that confirms a quotation is action_confirm.

static/src/js/order_button.js
await this.orm.call("sale.order", "action_confirm", [[this.props.record.resId]]);

Suppressing

// odooscan: ignore[OD604]
await this.orm.call("sale.order", "action_confirm_order", [[this.props.record.resId]]);

See suppressing a finding.