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
Stringto Model2. - added three attributes of type
[Struct], whereStructconforms toCodable,EquatableandHashableto 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 was0) - There is a problem because I am adding an attribute of type
[Struct]whereStructisCodable,Hashable, andEquatable. 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.