SwiftData Migration: Objects Created in Custom Migration Aren't Persisted or Queryable

Description: I'm experiencing a critical issue with SwiftData custom migrations where objects created during migration appear to be inserted successfully but aren't persisted or found by queries after migration completes. The migration logs show objects being created, but subsequent queries return zero results.

Problem Details:

I'm migrating from schema version V2 to V3, which involves:

Renaming Person class to GroupData

Keeping the same data structure but changing the class name

Using a custom migration stage to copy data from old to new schema

Migration Code:

swift static let migrationV2toV3 = MigrationStage.custom( fromVersion: LinkMapV2.self, toVersion: LinkMapV3.self, willMigrate: { context in do { let persons = try context.fetch(FetchDescriptor<LinkMapV2.Person>()) print("Found (persons.count) Person objects to migrate") // ✅ Shows 11 objects

        for person in persons {
            let newGroup = LinkMapV3.GroupData(
                id: person.id, // Same UUID
                name: person.name,
                // ... other properties
            )
            context.insert(newGroup)
            print("Inserted GroupData: '\(newGroup.name)'") // ✅ Confirms insertion
        }
        
        try context.save() // ✅ No error thrown
        print("Successfully migrated \(persons.count) objects") // ✅ Confirms save
        
    } catch {
        print("Migration error: \(error)")
    }
},
didMigrate: { context in
    do {
        let groups = try context.fetch(FetchDescriptor<LinkMapV3.GroupData>())
        print("Final GroupData count: \(groups.count)") // ❌ Shows 0 objects!
    } catch {
        print("Verification error: \(error)")
    }
}

) Console Output:

text === MIGRATION STARTED === Found 11 Person objects to migrate Migrating Person: 'Riverside of pipewall' with ID: 7A08C633-4467-4F52-AF0B-579545BA88D0 Inserted new GroupData: 'Riverside of pipewall' ... (all 11 objects processed) ... === MIGRATION COMPLETED === Successfully migrated 11 Person objects to GroupData === MIGRATION VERIFICATION === New GroupData count: 0 // ❌ PROBLEM: No objects found! What I've Tried:

Multiple context approaches:

Using the provided migration context

Creating a new background context with ModelContext(context.container)

Using context.performAndWait for thread safety

Different save strategies:

Calling try context.save() after insertions

Letting SwiftData handle saving automatically

Multiple save calls at different points

Verification methods:

Checking in didMigrate closure

Checking in app's ContentView after migration completes

Using both @Query and manual FetchDescriptor

Schema variations:

Direct V2→V3 migration

Intermediate V2.5 schema with both classes

Lightweight migration with @Attribute(originalName:)

Current Behavior:

Migration runs without errors

Objects appear to be inserted successfully

context.save() completes without throwing errors

But queries in didMigrate and post-migration return empty results

The objects seem to exist in a temporary state that doesn't persist

Expected Behavior:

Objects created during migration should be persisted and queryable

Post-migration queries should return the migrated objects

Data should be available in the main app after migration completes

Environment:

Xcode 16.0+

iOS 18.0+

SwiftData

Swift 6.0+

Key Questions:

Is there a specific way migration contexts should be handled for data to persist?

Are there known issues with object persistence in custom migrations?

Should we be using a different approach for class renaming migrations?

Is there a way to verify that objects are actually being written to the persistent store?

The migration appears to work perfectly until the verification step, where all created objects seem to vanish. Any guidance would be greatly appreciated!

Additional Context from my investigation:

I've noticed these warning messages during migration that might be relevant:

text SwiftData.ModelContext: Unbinding from the main queue. This context was instantiated on the main queue but is being used off it. error: Persistent History (76) has to be truncated due to the following entities being removed: (Person) This suggests there might be threading or context lifecycle issues affecting persistence.

Let me know if you need any additional information about my setup or migration configuration!

Answered by EndSunset in 864348022

This post is reposted since it is not clear, please have a look here: https://developer.apple.com/forums/thread/805865

SwiftData Migration: Objects Created in Custom Migration Aren't Persisted or Queryable
 
 
Q