SwiftData Migration Plan does not run custom migration stage

Hi, I'm trying to make some changes to my SwiftData model and I want to add a new non-optional property to one of my model classes.

My current model was not part of a VersionedSchema so I first encapsulated it into one

public enum FeynnDataModelsSchemaV1: VersionedSchema {
    public static var versionIdentifier: Schema.Version = .init(1, 0, 0)
    
    public static var models: [any PersistentModel.Type] {
        [FeynnDataModelsSchemaV1.Workout.self, FeynnDataModelsSchemaV1.Activity.self, FeynnDataModelsSchemaV1.ActivityRecord.self, FeynnDataModelsSchemaV1.WorkoutSession.self]
    }
}

Then I run the app and everything works as expected.

Secondly, I create the V2 and add the new property:

public enum FeynnDataModelsSchemaV2: VersionedSchema {
    public static var versionIdentifier: Schema.Version = Schema.Version(2, 0, 0)
    
    public static var models: [any PersistentModel.Type] {
        [FeynnDataModelsSchemaV2.Workout.self, FeynnDataModelsSchemaV2.Activity.self, FeynnDataModelsSchemaV2.ActivityRecord.self, FeynnDataModelsSchemaV2.WorkoutSession.self]
    }
}

extension FeynnDataModelsSchemaV2 {
    @Model
    final public class Activity: Hashable {
        ...
        public var activityType: ActivityType = ActivityType.traditionalStrengthTraining
        ...
   }
}

Lastly, I create the schema migration plan and add it to my modelContainer:

public enum FeynnDataModelsMigrationPlan: SchemaMigrationPlan {
    public static var schemas: [VersionedSchema.Type] = [
        FeynnDataModelsSchemaV1.self,
        FeynnDataModelsSchemaV2.self
    ]
    
    public static var stages: [MigrationStage] = [migrateV1toV2]
    
    public static var migrateV1toV2 = MigrationStage.custom(fromVersion: FeynnDataModelsSchemaV1.self, toVersion: FeynnDataModelsSchemaV2.self, willMigrate: {moc in
        let activities = try? moc.fetch(FetchDescriptor<Activity>())
        print("\(activities?.count ?? 919191991)")
    }, didMigrate: {moc in
        let activities = try? moc.fetch(FetchDescriptor<Activity>())
        print("\(activities?.count ?? 88888888)")
        activities?.forEach { activity in activity.activityType = .traditionalStrengthTraining }
        try? moc.save()
    })   
}
            if let container = try? ModelContainer(
                for: Workout.self, Activity.self, ActivityRecord.self, WorkoutSession.self,
                migrationPlan: FeynnDataModelsMigrationPlan.self,
                configurations: ModelConfiguration(cloudKitDatabase: .automatic)) {
                self.container = container
            } else {
                self.container = try ModelContainer(
                    for: Workout.self, Activity.self, ActivityRecord.self, WorkoutSession.self,
                    migrationPlan: FeynnDataModelsMigrationPlan.self,
                    configurations: ModelConfiguration(cloudKitDatabase: .none))
            }

After running this, the application runs as expected, but as soon as I render a view that references Activity.activityType the app crashes trying to get the value for my existing activities given that it is nil, pointing out that the migration stage was not ran? None of the print statements in the didMigrate or willMigrate can be found within the logs either.

I have tried several approaches creating more VersionedSchemas and I run into more issues such as Cannot use stuck migration with an unknown model version.

I feel like the current way of handling schema versions of SwiftData is very confusing and opaque for the developer to know what is going on. I don't know if the underlying database is picking the un-versioned schema, the V1 or the V2.

Is there anything I'm doing wrong? What can I do apart from making the new property optional and having a computed property that unwraps it giving it a default value when nil?

Thank you!

If you retrieve the store's metadata, there will be a "version checksum" for the current schema of the store. Does it match either of the version checksums for FeynnDataModelsSchemaV1 or FeynnDataModelsSchemaV2? The error you're receiving indicates that it does not, so schema migration doesn't know where to start or where to go. Each model change must be precisely managed and controlled as it changes that version checksum.

If you accidentally released your app without a versioned schema, how do you then use migration plans? @Frameworks Engineer

Did you find a solution for this? Many people are asking about this issue, but no solutions on any of the posts.

SwiftData Migration Plan does not run custom migration stage
 
 
Q