iOS 18.3: "Fatal error: Failed to validate ..." when calling fetchHistory for HistoryTransaction

I'm converting SwiftData models into structs so I can fetch them in the background. To know when and which ones I need to update, I'm using iOS 18's new HistoryTransaction.

Starting with iOS 18.3 (worked perfectly fine before), I'm getting this crash every time:

Thread 18: Fatal error: Failed to validate placeVideosIn.placeVideosIn because placeVideosIn is not a member of VideoPlacement

The crash is happening here:

static func findTransactions(after token: DefaultHistoryToken?) -> [DefaultHistoryTransaction] {
    var historyDescriptor = HistoryDescriptor<DefaultHistoryTransaction>()
    if let token {
        historyDescriptor.predicate = #Predicate { transaction in
            (transaction.token > token)
        }
    }

    var transactions: [DefaultHistoryTransaction] = []
    let taskContext = ModelContext(container)
    do {
        transactions = try taskContext.fetchHistory(historyDescriptor) // <- CRASH
    } catch let error {
        Logger.log.warning("findTransactions Error: \(error)")
    }

    return transactions
}

The SwiftData model has this enum property:

@Model
public final class Subscription {
    // ...
    public var placeVideosIn = VideoPlacement.defaultPlacement
    
}

The enum looks like this:

public enum VideoPlacement: Int {
    case inbox = 0
    case queueNext = 1
    case nothing = 2
    case defaultPlacement = 3
    case queueLast = 4
}

The enum has changed at one point, but I was expecting that change to be transparent/additive. It looked like this before:

public enum VideoPlacement: Int {
    case inbox, queue, nothing, defaultPlacement
}

Changing all values manually to e.g. .defaultPlacement did not fix the crash. What did fix it was deleting all HistoryTransactions:

var descriptor = HistoryDescriptor<DefaultHistoryTransaction>()
try modelContext.deleteHistory(descriptor)

For some reason, deleting all HistoryTransactions sometimes also deletes actual models. Is that to be expected?

Any idea how I could attempt to fix this issue?

I don't see your code snippet has anything obviously wrong. Given that the crash only happens in iOS 18.3, I'd suggest that you file a feedback report – If you do so, please share your report ID here for folks to track.

For some reason, deleting all HistoryTransactions sometimes also deletes actual models. Is that to be expected?

Definitely not. If you can provide a minimal project with detailed steps to reproduce the issue, I'll be intersted in taking a look.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Same crash happened in my project when using enum types in my Swift Data model along with the Swift Data history APIs. I found a less ideal solution to the problem was to use a @Transient property exposing my enum and have the underlying data backed by a more permeative type.

@Transient
var sessionType: TaskSessionType {
    get { TaskSessionType(rawValue: sessionTypeRaw) ?? .focus }
    set { sessionTypeRaw = newValue.rawValue }
}
private(set) var sessionTypeRaw: Int = TaskSessionType.focus.rawValue
iOS 18.3: "Fatal error: Failed to validate ..." when calling fetchHistory for HistoryTransaction
 
 
Q