Skip to content

[FIX] util/model: archive records relinked to _unknown#387

Open
apan-odoo wants to merge 1 commit intoodoo:masterfrom
odoo-dev:master-archive_unknown_records-apan
Open

[FIX] util/model: archive records relinked to _unknown#387
apan-odoo wants to merge 1 commit intoodoo:masterfrom
odoo-dev:master-archive_unknown_records-apan

Conversation

@apan-odoo
Copy link

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: removing1 hr.candidate (which is _mailing_enabled = True)2 relinks related mailing.mailing records to _unknown. Accessing those mailings may then raise:

('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

Footnotes

  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

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
@robodoo
Copy link
Contributor

robodoo commented Feb 20, 2026

Pull request status dashboard

@apan-odoo apan-odoo requested review from a team and Pirols February 20, 2026 12:26
@KangOl
Copy link
Contributor

KangOl commented Feb 20, 2026

upgradeci retry with always only hr

@aj-fuentes
Copy link
Contributor

aj-fuentes commented Feb 20, 2026

Example: removing1 hr.candidate (which is _mailing_enabled = True)2 relinks related mailing.mailing records to _unknown. Accessing those mailings may then raise:

This looks like the wrong solution. From what you describe what we are missing is a replace_records_reference_batch before removing hr.candidate. Or some direct SQL query

@aj-fuentes
Copy link
Contributor

For the record, I'm not against this patch. I just believe that it isn't the correct solution for the motivating issue.

@KangOl
Copy link
Contributor

KangOl commented Feb 20, 2026

Yes, it looks more like avoiding the traceback instead of fixing the real issue.

@apan-odoo
Copy link
Author

@aj-fuentes @KangOl I initially thought of fixing this in upgrade, but mailing.mailing only has the mailing_model_id so i guess the replace_record_references_batch suggestion may not apply here. Also, in the case I’m looking at, the fix involves the removal of hr.candidate. From what I understood in this commit:https://github.com/odoo/upgrade/commit/73f24282137574aa71445ab69b9e4c5f56e6550a it seems that records from hr.candidate are already mapped to the hr.applicant. However, I’m a bit unsure about the mailing.mailing records. Should we explicitly run a query to update the mailing_model_id to hr.applicant ?(haven't seen any example like this in upgrade repo). Since in v18 both models have _mailing_enabled = True, mapping candidate mailings to the applicant model seems correct, but I’d like to confirm before proceeding.
Thanks!

@aj-fuentes
Copy link
Contributor

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.

@apan-odoo
Copy link
Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants