I managed to create a minimal repro example:
import SwiftData
import SwiftUI
@Model
final class ParentModel {
var name: String
@Relationship(deleteRule: .cascade, inverse: \ChildModel1.parent)
var children: [ChildModel1]?
@Relationship(deleteRule: .cascade, inverse: \ChildModel2.parent)
var children2: [ChildModel2]?
init(name: String) {
self.name = name
}
}
@Model
final class ChildModel1 {
var name: String
@Relationship(deleteRule: .nullify)
var parent: ParentModel?
init(name: String) {
self.name = name
}
}
@Model
final class ChildModel2 {
var name: String
@Relationship(deleteRule: .nullify)
var parent: ParentModel?
init(name: String) {
self.name = name
}
}
struct ContentView: View {
@Environment(\.modelContext)
private var modelContext
var body: some View {
List {
Button("Create parent with children") {
createParentWithChildren()
}
Button("Delete") {
delete()
}
}
}
func createParentWithChildren() {
let parent = ParentModel(name: "Parent")
let child1 = ChildModel1(name: "Child 1")
let child2 = ChildModel2(name: "Child 2")
modelContext.insert(parent)
modelContext.insert(child1)
modelContext.insert(child2)
child1.parent = parent
child2.parent = parent
try! modelContext.save()
}
func delete() {
guard let parent = try! modelContext.fetch(FetchDescriptor<ParentModel>()).first else { return }
modelContext.delete(parent)
// This throws "Unexpected backing data for snapshot creation" fatal error
modelContext.rollback()
}
}
@main
struct PlaygroundAppApp: App {
private let container: ModelContainer
init() {
let schema = Schema([ParentModel.self, ChildModel1.self, ChildModel2.self])
let config = ModelConfiguration(schema: schema, isStoredInMemoryOnly: true)
container = try! ModelContainer(for: schema, configurations: [config])
}
var body: some Scene {
WindowGroup {
ContentView()
.modelContainer(container)
}
}
}
The fact that modulates if the problem occurs or not it number of different relationships on ParentModel. When there is only one relationship (e.g. only @Relationship(deleteRule: .cascade, inverse: \ChildModel1.parent) var children: [ChildModel1]?) everything seems to work fine. As soon as I add second relationship, the fatal error on rollback is being triggered if deleted model contains any active relationship. What is interesting - even if model have only one active relationship, let's say there is only 1 ChildModel1 that points to give model, the fatal error is being triggered on rollback.
Considering all this it looks to me like the problem actually lies inside Swift Data internals, so I've filled the feedback - FB22325366.