[dev] C4 - add config migration system by deruyter92 · Pull Request #3197 · DeepLabCut/DeepLabCut

@deruyter92 deruyter92 changed the title add config migration system [DEV] C4 - add config migration system

Feb 3, 2026

@deruyter92 deruyter92 changed the title [DEV] C4 - add config migration system [dev] C4 - add config migration system

Feb 3, 2026

C-Achard

Base automatically changed from jaap/replace_config_loaders_with_typed to feat/structured_configs

February 5, 2026 16:07

@deruyter92 deruyter92 changed the base branch from feat/structured_configs to jaap/cfg_3b_additional_fixes

February 18, 2026 12:45

Base automatically changed from jaap/cfg_3b_additional_fixes to feat/structured_configs

February 20, 2026 07:49

@deruyter92

@deruyter92

@deruyter92

@deruyter92

…ith validate_assignment=True)

This is necessary to prevent a bug:
The isinstance(data, cls): return data shortcut in MigrationMixin.migrate_then_validate (a model_validator(mode="wrap")). Pydantic re-enters this validator during validate_assignment, passing the current instance as data. The shortcut returned it unchanged, silently discarding every field update. This broke all assignment — not just validation, but even plain cfg.count = 42 was a no-op.

The problem is that model_validator(mode="wrap") wraps the entire validation pipeline, including validate_assignment flow. Migration should only run during construction, not on every field assignment.
The clean solution is to switch from mode="wrap" to mode="before" — it transforms raw input data before validation and doesn't participate in validate_assignment at all.

@deruyter92

@deruyter92 deruyter92 deleted the jaap/add_config_migration_system branch

February 20, 2026 12:33