[FIX] util/model: archive records relinked to _unknown#387
[FIX] util/model: archive records relinked to _unknown#387apan-odoo wants to merge 1 commit intoodoo:masterfrom
Conversation
When removing a model, some `IndirectReference` entries use
`set_unknown=True`. In that case, related records are kept and their
model reference is set to `_unknown`.
If those records remain active, they may still be accessible through
menus or actions. During upgrade checks (e.g. mock crawl), this can
trigger access errors when computed fields attempt to access the
`_unknown` model.
Example: removing[^1] `hr.candidate`
(which is `_mailing_enabled = True`)[^2]
relinks related `mailing.mailing` records to `_unknown`. Accessing those
mailings may then raise:
```py
('mass_mailing.mass_mailing_menu', 518, 'Email Marketing > Mailings', 710):
Traceback (most recent call last):
File "/tmp/tmp0l0nbe1m/migrations/base/tests/test_mock_crawl.py", line 333, in crawl_menu
self.mock_action(action_vals)
File "/tmp/tmp0l0nbe1m/migrations/base/tests/test_mock_crawl.py", line 346, in mock_action
return self.mock_act_window(action)
File "/tmp/tmp0l0nbe1m/migrations/base/tests/test_mock_crawl.py", line 506, in mock_act_window
mock_method(model, view, fields_list, domain, group_by)
File "/tmp/tmp0l0nbe1m/migrations/base/tests/test_mock_crawl.py", line 623, in mock_view_kanban
self.mock_web_read_group(model, view, domain, group_by, fields_list, limit_group=10)
File "/tmp/tmp0l0nbe1m/migrations/base/tests/test_mock_crawl.py", line 750, in mock_web_read_group
self.mock_web_search_read(model, view, [domain], fields_list)
File "/tmp/tmp0l0nbe1m/migrations/base/tests/test_mock_crawl.py", line 691, in mock_web_search_read
data = model.search_read(domain=domain, fields=fields_list, limit=80, order=filter_order(model))
File "/home/odoo/src/odoo/19.0/odoo/orm/models.py", line 5779, in search_read
return records._read_format(fnames=fields, **read_kwargs)
File "/home/odoo/src/odoo/19.0/odoo/orm/models.py", line 3744, in _read_format
vals[name] = convert(record[name], record, use_display_name)
File "/home/odoo/src/odoo/19.0/odoo/orm/models.py", line 6680, in __getitem__
return self._fields[key].__get__(self)
File "/home/odoo/src/odoo/19.0/odoo/orm/fields.py", line 1751, in __get__
self.compute_value(record)
File "/home/odoo/src/odoo/19.0/odoo/orm/fields.py", line 1917, in compute_value
records._compute_field_value(self)
File "/home/odoo/src/odoo/19.0/addons/mail/models/mail_thread.py", line 483, in _compute_field_value
return super()._compute_field_value(field)
File "/home/odoo/src/odoo/19.0/odoo/orm/models.py", line 4949, in _compute_field_value
determine(field.compute, self)
File "/home/odoo/src/odoo/19.0/odoo/orm/fields.py", line 81, in determine
return needle(*args)
File "/home/odoo/src/odoo/19.0/addons/mass_mailing/models/mailing.py", line 288, in _compute_total
total = self.env[mass_mailing.mailing_model_real].search_count(mass_mailing._get_recipients_domain())
File "/home/odoo/src/odoo/19.0/odoo/orm/models.py", line 1358, in search_count
query = self._search(domain, limit=limit)
File "/home/odoo/src/odoo/19.0/odoo/orm/models.py", line 5348, in _search
self.browse().check_access('read')
File "/home/odoo/src/odoo/19.0/odoo/orm/models.py", line 4112, in check_access
raise result[1]()
odoo.exceptions.AccessError: You are not allowed to access 'Unknown' (_unknown) records.
No group currently allows this operation.
Contact your administrator to request access if necessary.
```
To avoid this, records relinked to `_unknown` are now archived when the
target table has an active field.
This prevents broken configurations from being exposed while keeping
data for reference.
opw-5947913
upg-3910062
tbg-2461
[^1]: https://github.com/odoo/upgrade/blob/8c749b7b4e8ea5259e0644dc7a5715dbb18e06f8/migrations/hr_recruitment/saas~18.2.1.1/end-migrate.py#L7
[^2]: https://github.com/odoo/odoo/blob/18.0/addons/hr_recruitment/models/hr_candidate.py#L22
|
upgradeci retry with always only hr |
This looks like the wrong solution. From what you describe what we are missing is a |
|
For the record, I'm not against this patch. I just believe that it isn't the correct solution for the motivating issue. |
|
Yes, it looks more like avoiding the traceback instead of fixing the real issue. |
|
@aj-fuentes @KangOl I initially thought of fixing this in upgrade, but |
|
What you propose looks correct. Please open a PR, even if you are not sure yet what to do, we can move the discussion there. |
PR opened at: https://github.com/odoo/upgrade/pull/9547 |

When removing a model, some
IndirectReferenceentries useset_unknown=True. In that case, related records are kept and their model reference is set to_unknown.If those records remain active, they may still be accessible through menus or actions. During upgrade checks (e.g. mock crawl), this can trigger access errors when computed fields attempt to access the
_unknownmodel.Example: removing1
hr.candidate(which is_mailing_enabled = True)2 relinks relatedmailing.mailingrecords to_unknown. Accessing those mailings may then raise:To avoid this, records relinked to
_unknownare now archived when the target table has an active field.This prevents broken configurations from being exposed while keeping data for reference.
opw-5947913
upg-3910062
tbg-2461
Footnotes
https://github.com/odoo/upgrade/blob/8c749b7b4e8ea5259e0644dc7a5715dbb18e06f8/migrations/hr_recruitment/saas~18.2.1.1/end-migrate.py#L7 ↩
https://github.com/odoo/odoo/blob/18.0/addons/hr_recruitment/models/hr_candidate.py#L22 ↩