Sunday, May 3, 2026
1 change · saas-17.2
Resolved issues and error corrections
This fixes an upgrade issue where website configurator images could be mistaken for default website images and updated incorrectly. The change helps prevent upgrade failures and protects customized website images that are stored separately.
Original PR description
Method `configurator_apply()` may create new attachments that will have the same `key` and `website_id` as standard, default images:…
Method `configurator_apply()` may create new attachments that will have the same `key` and `website_id` as standard, default images: https://github.com/odoo/odoo/blob/f80094f43bcc464cc99fba6aa59f64659fe659b6/addons/website/models/website.py#L737-L752
Standard images should be updated from the source of the `website` module, but those created by the configurator will have their binary content stored in the filestore and therefore have no need to be updated.
As of right now however, we don't make this distinction when updating `website` data, the following line:
https://github.com/odoo/odoo/blob/f80094f43bcc464cc99fba6aa59f64659fe659b6/addons/website/models/ir_module_module.py#L162
will return both the standard attachment and the one originating from the configurator (due to the same `key` and `website_id`).
The fix is to tighten the `search` by filtering out records that have `store_fname` set.
This issue was discovered in many databases when upgrading to `saas~17.2` and a few also had this problem when upgrading to `17.0`. Here is an example traceback from one of the request:
```
Traceback (most recent call last):
File "/home/odoo/src/odoo/saas-17.2/odoo/service/server.py", line 1295, in preload_registries
registry = Registry.new(dbname, update_module=update_module)
File "<decorator-gen-16>", line 2, in new
File "/home/odoo/src/odoo/saas-17.2/odoo/tools/func.py", line 87, in locked
return func(inst, *args, **kwargs)
File "/home/odoo/src/odoo/saas-17.2/odoo/modules/registry.py", line 120, in new
odoo.modules.load_modules(registry, force_demo, status, update_module)
File "/home/odoo/src/odoo/saas-17.2/odoo/modules/loading.py", line 476, in load_modules
processed_modules += load_marked_modules(env, graph,
File "/home/odoo/src/odoo/saas-17.2/odoo/modules/loading.py", line 364, in load_marked_modules
loaded, processed = load_module_graph(
File "/home/odoo/src/odoo/saas-17.2/odoo/modules/loading.py", line 296, in load_module_graph
module.write({'state': 'installed', 'latest_version': ver})
File "/home/odoo/src/odoo/saas-17.2/addons/website/models/ir_module_module.py", line 95, in write
module._theme_load(website)
File "/home/odoo/src/odoo/saas-17.2/addons/website/models/ir_module_module.py", line 239, in _theme_load
module._update_records(model_name, website)
File "/home/odoo/src/odoo/saas-17.2/addons/website/models/ir_module_module.py", line 165, in _update_records
imd = self.env['ir.model.data'].search([('model', '=', find._name), ('res_id', '=', find.id)])
File "/home/odoo/src/odoo/saas-17.2/odoo/fields.py", line 5183, in __get__
raise ValueError("Expected singleton: %s" % record)
ValueError: Expected singleton: ir.attachment(797, 725)
```