Thanks for being a part of WWDC25!

How did we do? We’d love to know your thoughts on this year’s conference. Take the survey here

'NSInvalidArgumentException', reason: 'Duplicate version checksums across stages detected.'

I have an iOS app using SwiftData with VersionedSchema. The schema is synchronized with an CloudKit container.

I previously introduced some model properties that I have now removed, as they are no longer needed. This results in the current schema version being identical to one of the previous ones (except for its version number).

This results in the following exception:

'NSInvalidArgumentException', reason: 'Duplicate version checksums across stages detected.'

So it looks like we cannot have a newer schema version with an identical content to an older schema version.

The intuitive way would be to re-add the old (identical) schema version to the end of the "schemas" list property in the SchemaMigrationPlan, in order to signal that it is the newest one, and to add a migration stage back to it, thus:

public enum MySchemaMigrationPlan: SchemaMigrationPlan {

    public static var schemas: [any VersionedSchema.Type] {
        [
            SchemaV100.self,
            SchemaV101.self,
            SchemaV100.self
        ]
    }

    public static var stages: [MigrationStage] {
        [
            migrateV100toV101,
            migrateV101toV100
       ]
   }

However, I am not sure if this is the right way to go, as previously, as I wanted to write unit tests for schema migration and rollback, I tried defining an inverse for each migration stage, so that I could trigger a migration and a rollback from a unit test, which resulted in an exception saying that it is not supported to downgrade a VersionedSchema.

I must admit that I solved the original problem by introducing a dummy model property that I will later remove. What would have been the correct approach?

'NSInvalidArgumentException', reason: 'Duplicate version checksums across stages detected.'
 
 
Q