SwiftData document-based app crashes on undo/redo without ModelContext.transaction(block:)

Overview

I'm developing a document-based app for macOS using SwiftData. When I undo/redo changes using Command-Z/Command-Shift-Z, the app reliably crashes with the following error:

SwiftData/ModelSnapshot.swift:46: Fatal error: Unexpected backing data for snapshot creation: SwiftData._FullFutureBackingData<DocumentTest.ChildItem>

And before the app crashes, what always happens is that UndoManager stops removing/restoring instances of ChildItem (but continues to remove/restore instances of ParentItem).

The issue goes away when I enclose the relevant code in ModelContext.transaction(block:). However, this shouldn't be necessary, as ModelContext.autosaveEnabled is true by default.

The issues are occurring with Xcode 26.4 (17E192) and macOS Tahoe 26.4 (25E246).

I have modified the macOS Document App project template to showcase the issue. The sample project, along with a screen recording of the crash, can be downloaded from here:

https://drive.google.com/drive/folders/13bCB1qRZ6273BI81zW2zUUBraSvv6p5w?usp=share_link

Is this expected behavior or should I file a bug report in Feedback Assistant?

Steps to Reproduce

To recreate the issue, follow these steps:

  1. Download and extract the "Xcode Project.zip" file linked above.
  2. Open the extracted "DocumentTest" project in Xcode.
  3. Build and run the "DocumentTest" app.
  4. In the document selection window, click "New Document" at the bottom-left.
  5. In the app, click the "+" button at the top-right to add a ParentItem with ChildItems.
  6. Click on the added ParentItem's button to add another ChildItem to it.
  7. Repeat steps 5–6 until you have 5 ParentItems with an additional ChildItem.
  8. Press Command-Z 10 times to undo all the changes.
  9. Press Command-Shift-Z 10 times to redo all the changes.
  10. Repeat steps 8–9 until UndoManager stops removing/restoring the additional ChildItem, and continue repeating them until the app eventually crashes (you may have to repeat them 5–10 times before the issue occurs).

If you uncomment the ModelContext.transaction(block:) at line 13 of ContentView.swift and repeat the same steps above, no ChildItems will go missing and the app will not crash.

Code

ParentItem Model

@Model
final class ParentItem {
    var timestamp: Date
    
    @Relationship(
        deleteRule: .cascade,
        inverse: \ChildItem.parentItem
    )
    var childItems: [ChildItem] = []
 
    init(timestamp: Date) {
        self.timestamp = timestamp
    }
}

ChildItem Model

@Model
final class ChildItem {
    var index: Int
    
    var parentItem: ParentItem?

    init(index: Int) {
        self.index = index
    }
}

Creating, Inserting, and Linking ParentItem and ChildItem

// Create and insert ParentItem

let newParentItem = ParentItem(
    timestamp: Date()
)
modelContext.insert(newParentItem)

// Create and insert ChildItems

var newChildItems: [ChildItem] = []

for index in 0..<Int.random(in: 2...8) {
    let newChildItem = ChildItem(index: index)
    newChildItems.append(newChildItem)
    modelContext.insert(newChildItem)
}

/* Establish relationship between
 ParentItem and ChildItems */

for newChildItem in newChildItems {
    newParentItem.childItems.append(
        newChildItem
    )
    newChildItem.parentItem = newParentItem
}

Adding an Additional ChildItem to ParentItem

// Uncommenting this block fixes the crash
// try! modelContext.transaction {
    // Create and insert the new ChildItem
    
    let newChildItem = ChildItem(
        index: parentItem.childItems.count
    )
    modelContext.insert(newChildItem)
    
    // Establish relationship to parentItem

    parentItem.childItems.append(newChildItem)
    newChildItem.parentItem = parentItem
// }
SwiftData document-based app crashes on undo/redo without ModelContext.transaction(block:)
 
 
Q