Build domain filters as lists of triples: [('field_name', 'operator', value)]; supported operators include '=', '!=', 'like', 'ilike', 'in', 'not in', '>=', '<='
Combine conditions with logical prefixes: ['&', condition1, condition2] for AND, ['|', condition1, condition2] for OR; the default when listing multiple conditions without a prefix is AND
Before filtering on a field, check whether it is a stored vs computed field using the model's fields_get() method or the Odoo source; stored fields map to database columns and are filterable
For non-stored computed fields, retrieve all candidate records and filter in Python/application code — attempting to filter on them via the ORM domain will raise an error or return empty results
Use 'limit' and 'offset' kwargs in search_read to paginate results and avoid loading entire tables
Known gotchas
Computed fields that are marked store=True are written to the database and can be filtered; computed fields with store=False exist only at runtime and cannot be used in domain filters — check the field definition before building a filter
The 'like' operator in Odoo is case-sensitive and uses SQL LIKE syntax with '%' wildcards; use 'ilike' for case-insensitive substring matches — this is the opposite of what developers coming from other ORMs expect
Many2many and One2many relational fields support 'in' filtering only on IDs; passing display names or external identifiers in a domain filter against a relational field returns no results without an explicit join or name search
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp