SwiftData ModelContext Fetch Crashing

I'm currently using Xcode 16 Beta (16A5171c) and I'm getting a crash whenever I attempt to fetch using my ModelContext in my SwiftUI video using the environment I'm getting a crash specifically on iOS 18 simulators.

I've opened up a feedback FB13831520 but it's worth noting that I can run the code I'll explain in detail below on iOS 17+ simulator and devices just fine.

I'm getting the following crash:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'The specified URI is not a valid Core Data URI: x-coredata:///MyApp/XXXXX-XXXXX-XXXX-XXXX-XXXXXXXXXXXX'

It's almost as if on iOS18 SwiftData is unable to find the file on the simulator to perform CRUD operations.

All I'm doing in my project is simply fetching data using the modelContext.

    func contains(_ model: MyModel, in context: ModelContext) -> Bool {
        let objId = palette.persistentModelID
        let fetchDesc = FetchDescriptor<MyModel>(predicate: #Predicate { $0.persistentModelID == objId })
        let itemCount = try? context.fetchCount(fetchDesc)
        return itemCount != 0
    }
Answered by DTS Engineer in 793178022

Just to confirm that FB13831520 and FB13872901 were diagnosed as the same issue on the system side. The relevant team is actively working on that as of today. Thanks for filing the feedback reports.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

The project attached to your feedback report is empty. Would you mind to attach it again and make sure it is uploaded correctly? You can also attach to your post here, which is visible to the whole community.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

I have the exact same error. For me it does work when building for the iOS 17.5 simulator, and not for the iOS 18 simulator.

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'The specified URI is not a valid Core Data URI: x-coredata:///Workout/5F9352C2-50DA-422B-BDF6-C3BA3AD73067

@DTS Engineer I encountered the same issue where there's a one-to-many relationship in Swift Data, and triggering an error while iterating through items in a subview.

I've created a "SwiftDataErrorDemo" project to facilitate reproducing the error. Since I can't upload the entire project, I'll describe it through specific steps:

  1. Create a SwiftUI project using Xcode 16.0 beta (16A5171c) and select SwiftData.
  2. Create Expense and Category models respectively.
@Model
final class Expense {
    var acount: Double
    var timestamp: Date
    var category: Category?
    
    init(acount: Double, timestamp: Date, category: Category) {
        self.acount = acount
        self.timestamp = timestamp
        self.category = category
    }
}

@Model
class Category {
    var name: String
    @Relationship(deleteRule: .cascade)
    var expenses: [Expense]?
    var timestamp: Date
    
    init(name: String, timestamp: Date) {
        self.name = name
        self.timestamp = timestamp
    }
}
  1. Add "insert test data code" in ContentView.
struct ContentView: View {
    @Environment(\.modelContext) private var modelContext
    @Query private var categories: [Category]

    var body: some View {
        NavigationSplitView {
            List {
                NavigationLink {
                    ExpensesListView()
                } label: {
                    Text("Trigger BUG")
                }
            }
        } detail: {
            Text("Select an item")
        }
        .onAppear {
            let category = Category(name: "🛍️", timestamp: .now)
            modelContext.insert(category)

            let newExpense = Expense(acount: Double.random(in: 20...30), timestamp: .now, category: category)
            let newExpense2 = Expense(acount: Double.random(in: 20...30), timestamp: .now, category: category)
            modelContext.insert(newExpense)
            modelContext.insert(newExpense2)
        }
    }
}
  1. Fetch the Expense result set in ExpensesListView.
struct ExpensesListView: View {
    @Query(filter: #Predicate<Expense> { $0.category?.name == "🛍️" })
    private var expenses: [Expense]

    var body: some View {
        List {
            if expenses.isEmpty {
                ContentUnavailableView("No Data", systemImage: "magnifyingglass")
            } else {
                Text("Total: \(expenses.count)")
            }
        }
        .onAppear {
            print("Enter ExpensesListView")
        }
    }
}

Now, when you run SwiftDataErrorDemo using the iOS17 simulator, you can navigate to the ExpensesListView view normally. However, when running it with the iOS18 simulator, navigating to the ExpensesListView view will result in an error (or the interface will "freeze," with memory skyrocketing).

Just to confirm that FB13831520 and FB13872901 were diagnosed as the same issue on the system side. The relevant team is actively working on that as of today. Thanks for filing the feedback reports.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Are there any updates?

It seems to crash with any SwiftData related id, but it's fine when just using the primitive values

        let id = model.persistentModelID
        let descriptor = FetchDescriptor<cache>(
            predicate: #Predicate { $0.cacheOf.persistentModelID == id }
//            predicate: #Predicate { $0.cacheOf.id == id } or this
        )
        let result = (try? self.modelContext.fetch(descriptor) // 💥 crash here!
            .first)
        return result

I'm getting similar crashes with SwiftData...on multiple machines.

let id = model.persistentModelID
        let descriptor = FetchDescriptor<cache>(
            predicate: #Predicate { $0.cacheOf.persistentModelID == id }
//            predicate: #Predicate { $0.cacheOf.id == id } or this
        )
        let result = (try? self.modelContext.fetch(descriptor) // 💥 crash here!
            .first)
        return result

Some update on this! So turns out, I was fetching a model that was just created. The system can't find the model. I guess this was a cache miss in swiftData?!

To Fix This: In your modelActor try? self.modelContext.save()

  • basically, you want the modelContext to write into disk to create the persistentModelID

Good luck!

SwiftData ModelContext Fetch Crashing
 
 
Q