Skip to content

[19.0][FIX] base: populate default_user_group.implied_ids before dele…#5601

Open
GladistoneSouza wants to merge 1 commit intoOCA:19.0from
GladistoneSouza:19.0-fix-base-default-user-group-ordering
Open

[19.0][FIX] base: populate default_user_group.implied_ids before dele…#5601
GladistoneSouza wants to merge 1 commit intoOCA:19.0from
GladistoneSouza:19.0-fix-base-default-user-group-ordering

Conversation

@GladistoneSouza
Copy link
Copy Markdown

Summary

_init_default_user_group in openupgrade_scripts/scripts/base/19.0.1.3/post-migration.py is invoked after delete_records_safely_by_xml_id(['base.default_user', ...]). Because it short-circuits when base.default_user no longer resolves, the migration always produces a base.default_user_group with an empty implied_ids set — so users
created after a migration stop inheriting the default group set that the deleted base.default_user carried.

Moving _init_default_user_group(env) to run before the delete fixes the transfer.

Root cause

The helper starts with:

def _init_default_user_group(env):
    default_user = env.ref("base.default_user", raise_if_not_found=False)                                                                                                                                                                                                                                                                                         
    if not default_user:
        return                                                                                                                                                                                                                                                                                                                                                    
    env.ref("base.default_user_group").write(             
        {"implied_ids": [Command.set(default_user.group_ids.ids)]}                                                                                                                                                                                                                                                                                                
    )                                                                                                                                                                                                                                                                                                                                                             

The current migrate() calls the deletion before the transfer:

def migrate(env, version):                                
    openupgrade.load_data(env, "base", "19.0.1.3/noupdate_changes_work.xml")
    openupgrade.delete_records_safely_by_xml_id(                                                                                                                                                                                                                                                                                                                  
        env,                                                                                                                                                                                                                                                                                                                                                      
        ["base.ir_filters_delete_own_rule", "base.default_user"],                                                                                                                                                                                                                                                                                                 
    )                                                                                                                                                                                                                                                                                                                                                             
    # … other helpers …                                   
    _init_default_user_group(env)   # too late — base.default_user is gone                                                                                                                                                                                                                                                                                        

After the delete, env.ref("base.default_user", raise_if_not_found=False) returns None, _init_default_user_group hits its if not default_user: return guard, and the implied_ids write never happens. The new base.default_user_group remains empty.

Fix

Swap the order: populate the new group while the old user still exists, then delete.

def migrate(env, version):                                
    openupgrade.load_data(env, "base", "19.0.1.3/noupdate_changes_work.xml")
    _init_default_user_group(env)
    openupgrade.delete_records_safely_by_xml_id(                                                                                                                                                                                                                                                                                                                  
        env,
        ["base.ir_filters_delete_own_rule", "base.default_user"],                                                                                                                                                                                                                                                                                                 
    )                                                     
    # … other helpers …

Diff: +5 / -1 (the _init_default_user_group call moves; a short comment is added explaining the ordering constraint). No change to _init_default_user_group itself or to any other helper.

Impact

With the ordering bug in place, every 18 → 19 migration silently loses the default group set for future user creations. Existing users are unaffected — their explicit group memberships are preserved — but newly created users no longer receive the defaults automatically, which is the exact behavior base.default_user_group was introduced to provide.

Evidence

Validated against two real Odoo 18 production backups by running the full upgrade pipeline four times, flipping only this two-line ordering:

Run Backup OpenUpgrade default_user_group.implied_ids
baseline (source) default_user.group_ids on Odoo 18 37
A 2026-04-21 original 0
B 2026-04-21 patched 37
B 2026-04-24 patched 37
A 2026-04-24 reverted (original) 0
B 2026-04-24 patched again, same DB 37

A/B/A/B on the same database confirms the behavior is deterministic and tied solely to this call ordering. Source group_ids count (37) is preserved end-to-end only when the patch is applied.

Checklist

  • Only the ordering inside migrate() changes; _init_default_user_group itself is untouched.
  • Comment added explaining why the helper must run before the delete, so the constraint is visible to future editors.
  • Verified against two distinct production backups.

…ting default_user

`_init_default_user_group` reads `default_user.group_ids` and writes them
into `default_user_group.implied_ids`. With the previous ordering,
`delete_records_safely_by_xml_id` removed `base.default_user` first, so
`env.ref('base.default_user', raise_if_not_found=False)` returned `None`
inside `_init_default_user_group` and the function short-circuited via its
`if not default_user: return` guard. The new `default_user_group` ended up
with an empty `implied_ids`, and users created post-migration did not
inherit the default group set.

Moving `_init_default_user_group(env)` to run before the delete fixes the
transfer.

Verified on two real Odoo 18 production backups (2026-04-21 and
2026-04-24): without the patch `default_user_group.implied_ids` is 0; with
the patch it matches the source `default_user.group_ids` count (37 in both
cases). Reverting the patch against the same database reproduces the zero
state — A/B/A/B confirmed.

Signed-off-by: Gladistone Souza <gladistone09@gmail.com>
@OCA-git-bot OCA-git-bot added mod:openupgrade_scripts Module openupgrade_scripts series:19.0 labels Apr 24, 2026
Comment on lines +102 to +105
# _init_default_user_group must run BEFORE deleting base.default_user,
# because it reads default_user.group_ids to populate
# default_user_group.implied_ids. Running it after the delete leaves
# the new group with an empty implied_ids set.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the commit message is verbose enough, so this seems overkill to me. good catch though

Copy link
Copy Markdown
Contributor

@remi-filament remi-filament left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @GladistoneSouza
The description is quite long and seems generated by IA, the fix is indeed needed !

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

Labels

mod:openupgrade_scripts Module openupgrade_scripts series:19.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants