Bug? SwiftData + inheritance + optional many-to-one relationship

I've spent a few months writing an app that uses SwiftData with inheritance. Everything worked well until I tried adding CloudKit support. To do so, I had to make all relationships optional, which exposed what appears to be a bug. Note that this isn't a CloudKit issue -- it happens even when CloudKit is disabled -- but it's due to the requirement for optional relationships.

In the code below, I get the following error on the second call to modelContext.save() when the button is clicked:

Could not cast value of type 'SwiftData.PersistentIdentifier' (0x1ef510b68) to 'SimplePersistenceIdentifierTest.Computer' (0x1025884e0).

I was surprised to find zero hit when Googling "Could not cast value of type 'SwiftData.PersistentIdentifier'".

Some things to note:

  • Calling teacher.computers?.append(computer) instead of computer.teacher = teacher results in the same error.
  • It only happens when Teacher inherits Person.
  • It only happens if modelContext.save() is called both times.
  • It works if the first modelContext.save() is commented out.
  • If the second modelContext.save()is commented out, the error occurs the second time the model context is saved (whether explicitly or implicitly).

Keep in mind this is a super simple repro written to generate on demand the error I'm seeing in a normal app. In my app, modelContext.save() must be called in some places to update the UI immediately, sometimes resulting in the error seconds later when the model context is saved automatically. Not calling modelContext.save() doesn't appear to be an option.

To be sure, I'm new to this ecosystem so I'd be thrilled if I've missed something obvious! Any thoughts are appreciated.

import Foundation
import SwiftData
import SwiftUI

struct ContentView: View {
    @Environment(\.modelContext) var modelContext
    
    var body: some View {
        VStack {
            Button("Do it") {
                let teacher = Teacher()
                let computer = Computer()
                
                modelContext.insert(teacher)
                modelContext.insert(computer)
                
                try! modelContext.save()
                
                computer.teacher = teacher
                
                try! modelContext.save() 
            }
        }
    }
}

@Model
class Computer {
    @Relationship(deleteRule: .nullify)
    var teacher: Teacher?
    
    init() {}
}

@Model
class Person {
    init() {}
}

@available(iOS 26.0, macOS 26.0, *)
@Model
class Teacher: Person {
    @Relationship(deleteRule: .nullify, inverse: \Computer.teacher)
    public var computers: [Computer]? = []
    
    override init() {
        super.init()
    }
}

Do you have a feedback report yet? If not, would you mind to file one and share your report ID here? Thanks.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Thanks Ziqiao, I just did: FB21576369

Same. Given this schema:

This test crashes on line 49:

With: Could not cast value of type 'SwiftData.PersistentIdentifier' (0x1f574d070) to 'SwiftDataTest.Member' (0x102a2c868).

If I make ClubTeam not a subclass of Team, no problem.

Feedback ID: FB21576779

@DTS Engineer I submitted feedback a week ago but haven't heard anything. Should I expect a response? At this point, I can't enable CloudKit. I'd be happy to implement a workaround in the near term if one's available.

Hello, I am planning a project using SwiftData and inheritance with CloudKit but I am quite concerned about running into this bug. When I click the link to the FB ID above, it comes up empty as do searches for it. Does anyone know the current status?

@poirotsj it's still open, and no one has reached out to me. Considering it's happening to (at least) a few of us, I'd recommend using an alternative approach.

Bug? SwiftData + inheritance + optional many-to-one relationship
 
 
Q