SwiftData 'simple' migration failing

This is a long post, so let me start with a summary: I am attempting to implement what "ought to be" a simple SwiftData migration, and am receiving the following fatal error from the ModelContainer initializer:

NSCocoaErrorDomain Code=134504 "Cannot use staged 
migration with an unknown model version."

The crash occurs both in the Simulator and on a physical device.

Both the original schema and the new schema load and run as expected if loaded from scratch — so I conclude the Models are OK; it is the migration from the original schema to the new schema which is the issue.

I have reported this as FB22652791 and Technical Incident Case # 19893980. I have two model projects available — one contrived, the other using my actual SwiftData models.

Now the Details

I am developing a SwiftUI/SwiftData app. I am (currently) using Xcode 26.5-beta-3.

I set up an alpha-test build using the following approach:

public class DatabaseSchema {
	public let dbSchema: Schema = Schema([
		Model1.self, ... , Model16.self
	], version: Schema.Version(0, 9, 0))
	
	public var modelContainer: ModelContainer {
		let container: ModelContainer
		let modelConfiguration = ModelConfiguration(schema: dbSchema,
				isStoredInMemoryOnly: false)
	
	do {
		container = try ModelContainer(for: dbSchema,
				migrationPlan: nil,
				configurations: [modelConfiguration])
	} catch {
		fatalError("Failed to creae model conainer")
	}
	return container
}

This defines database version 0.9.

For version 1.0, I made three changes to the database:

  • added an attribute of type String to Model2.
  • added three attributes of type [Struct], where Struct conforms to Codable, Equatable and Hashable to Model3, and
  • added a new model (which I'll call Model17)

I define two schemas:

public enum Schema090: VersionedSchema {
	public static var versionIdentifier = Schema.Version(0, 9, 0)
	public static var models: [any PersistentModel.Type] = [
		Model1.self, Schema090.Model2.self, 
		Schema090.Model3.self, ... ]
}

and

public enum Schema100: VersionedSchema {
	public static var versionIdentifier = Schema.Version(1, 0, 0)
	public static var models: [any PersistentModel.Type] = [
		Model1.swift, Schema100.Model2.self,
		Schema100.Model3.self, ..., Model16.self, 
		Schema100.Model17.self ]
}

For models that changed, I use the following approach:

public typealias Model3 = Schema100.Model3

extension Schema090 {
	@Model final class Model3 {
		...
	}
	
	public init() {
		...
	}
}

extension Schema100 {
	@Model final class Model3 {
		...
		<added attributes, initialized>
	}
	
	public init() {
		...
	}
}

The DatabaseSchema class was modified as follows:

public class DatabaseSchema {
	public let dbSchema: Schema = Schema([
		Model1.self, Schema100.Model2.self, Schema100.Model3.self,
		... , Model16.self, Schema100.Model17.self
	], version: Schema.Version(1, 0, 0))
	
	public var modelContainer: ModelContainer {
		let container: ModelContainer
		let modelConfiguration = ModelConfiguration(schema: dbSchema,
				isStoredInMemoryOnly: false)
	
	do {
		container = try ModelContainer(for: dbSchema,
				migrationPlan: MigrationPlan.self,
				configurations: [modelConfiguration])
	} catch {
		fatalError("Failed to creae model conainer")
	}
	return container
}

where the migration plan is the trivial custom migration that makes sure that all added attributes of existing records are properly initialized.

enum MigrationPlan: SchemaMigrationPlan {
	static var schemas: [any VersionedSchema.Type] = [
		Schema090.self, Schema100.self ]
	
	static var stages: [MigrationStage] = [version090ToVersion100]
	
	static let version090ToVersion100 = 
		MigrationStage(fromVersion: Schema090.self,
			toVersion: Schema100.self, willMigrate: { _ in },
			didMigrate: { context in
		let models = try context.fetch(
			FetchDescriptor<Schema100.Model3>())
		for model in models {
			< initial the added attributes >
		{
		try context.save()
	})
}

This is all simple stuff. Nothing particularly fancy here. But running this code always crashes in the ModelContainer initializer. In my two sample projects, I get two different error messages —

  • in the contrived example, the error message is
Code=134110 "An error occurred during persistent store migration."
reason=Cannot migrate store in-place: Validation error missing 
attribute values on mandatory destination attribute, ...

and in the sample project that uses my actual data model, I get

NSCocoaErrorDomain Code=134504 "Cannot use staged 
migration with an unknown model version."

My Thoughts

Since obviously most folks are doing SwiftData migrations without the problems I am experiencing, the obvious possibilities are

  • I'm doing something stupid that I just don't see.
  • There is a problem because the original schema was given a version value of Schema.Version(0, 9, 0). (i.e., major version number was 0)
  • There is a problem because I am adding an attribute of type [Struct] where Struct is Codable, Hashable, and Equatable. I.e., migration isn't working properly with attributes which are stored as their codable representations.

Or maybe something else? In any case, any help you can offer would be greatly appreciated.

The issue seems to be triggered because your new attribute doesn't have a default value. Would you mind to try the following to check if the issue goes away?

  • Give the new attribute a default value.
  • Make the new attribute optional (so it's default value is nil).

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

I went through my entire schema and made sure that every attribute and every relationship in all 17 models was either optional or had a default value.

I reloaded the app from TestFlight (restoring the old schema (v0.9.0) and populated it with some records. I then ran the new version of the app (with schema v1.0.0 and all the added default values) and got the same error:

"Cannot use staged migration with an unknown model version."

Is it possible that the lack of default values in the v0.9.0 schema is the problem? (I.e., migration just can't deal with a non-optional without a default value at all? Not just for changed attributes? Or is there something else that I'm missing?

I think I just uncovered something important.

I have a simple sample app in which the v1 schema had a single Model. I was able to migrate it to v2 successfully.

But then, I added a second Model to the v2 schema. And the migration crashed. That is, the v1 schema had one Model and the v2 schema had 2 Models.

If, in fact, this is the source of the migration crash, the question then becomes, "How do I add a Model to an existing database without destroying all of the data previously stored in the database?"

NOTE: In this simple case, the second Model is independent of the first Model. But in real life, I'd like to both

  • add a new Model to the database, and
  • add @Relationships between that Model and the other Models already present.

Is this possible? And if so, can someone provide insight into how this could be done? (I note that I can't remember seeing any migrations that involved Relationships...)

I'd need to look into the code then. Is it possible that you provide a minimal project with detailed steps that demonstrates the issue? I've been pretty swamped as WWDC26 is right around the corner, but should be able to look into that after the conference, if not earlier.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

I fully understand your current time pressures and priorities — no worries.

I just sent the sample code off to Developer Tech Support. Instructions are in the email. If you have any questions, please feel free to give me a call or email.

SwiftData 'simple' migration failing
 
 
Q