Thanks for being a part of WWDC25!

How did we do? We’d love to know your thoughts on this year’s conference. Take the survey here

SwiftData 100% crash when fetching history with codable (test included!)

SwiftData crashes 100% when fetching history of a model that contains an optional codable property that's updated:

SwiftData/Schema.swift:389: Fatal error: Failed to materialize a keypath for someCodableID.someID from CrashModel. It is possible that this path traverses a type that does not work with append(), please file a bug report with a test.

Would really appreciate some help or even a workaround.

Code:

import Foundation
import SwiftData
import Testing

struct VaultsSwiftDataKnownIssuesTests {

    @Test
    func testCodableCrashInHistoryFetch() async throws {
        let container = try ModelContainer(
            for: CrashModel.self,
            configurations: .init(
                isStoredInMemoryOnly: true
            )
        )
        let context = ModelContext(container)
        try SimpleHistoryChecker.hasLocalHistoryChanges(context: context)

        // 1: insert a new value and save
        let model = CrashModel()
        model.someCodableID = SomeCodableID(someID: "testid1")
        context.insert(model)
        try context.save()

        // 2: check history it's fine.
        try SimpleHistoryChecker.hasLocalHistoryChanges(context: context)

        // 3: update the inserted value before then save
        model.someCodableID = SomeCodableID(someID: "testid2")
        try context.save()

        // The next check will always crash on fetchHistory with this error:
        /*
         SwiftData/Schema.swift:389: Fatal error: Failed to materialize a keypath for someCodableID.someID from CrashModel. It is possible that this path traverses a type that does not work with append(), please file a bug report with a test.
         */
        try SimpleHistoryChecker.hasLocalHistoryChanges(context: context)
    }
}

@Model final class CrashModel {

    // optional codable crashes.
    var someCodableID: SomeCodableID?

    // these actually work:
    //var someCodableID: SomeCodableID
    //var someCodableID: [SomeCodableID]

    init() {}
}

public struct SomeCodableID: Codable {
    public let someID: String
}

final class SimpleHistoryChecker {
    static func hasLocalHistoryChanges(context: ModelContext) throws {
        let descriptor = HistoryDescriptor<DefaultHistoryTransaction>()
        let history = try context.fetchHistory(descriptor)
        guard let last = history.last else {
            return
        }
        print(last)
    }
}
SwiftData 100% crash when fetching history with codable (test included!)
 
 
Q