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 randomly crashes with the following error:
SwiftData/BackingData.swift:425: Fatal error: Failed to retrieve the identifier for \ChildItem.parentItem from KnownKeysDictionary:KnownKeysMap: ["parentItem": 2, "isModified": 1, "index": 0] values: [Optional(0), Optional(false), Optional(DocumentTest.ParentItem)]
SwiftData._KKMDBackingData<DocumentTest.ChildItem>
And sometimes, instead of the app crashing, my created @Model objects simply disappear. They do not reappear in the @Query on undo/redo.
Both of these issues go away when I set
modelContext.autosaveEnabled = false
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 project, along with a screen recording of the crash, can be downloaded from here:
https://drive.google.com/drive/folders/1aDO34QleTm_rB9BuvVGjzzAP6jDXOc-o?usp=share_link
Has anyone else experienced this? I'd like to know if this is a bug in the autosave feature of SwiftData and if I should file a bug report via Feedback Assistant.
Steps to Reproduce
To recreate the issue, follow these steps:
Download and extract the "Xcode Project.zip" file linked above.
Open the extracted "DocumentTest" project in Xcode.
Build and run the "DocumentTest" app.
In the document selection window, click "New Document" at the bottom-left.
In the app, click the "+" button at the top-right to add a ParentItem with ChildItems.
Click on the added ParentItem's button to modify one of its ChildItems.
Repeat steps 5–6 until you have 5 ParentItems with a modified ChildItem.
Press Command-Z 10 times to undo all the changes.
Press Command-Shift-Z 10 times to redo all the changes.
Repeat steps 8–9 until either the app crashes or some of the 5 ParentItems go missing in the list (you may have to repeat them 10–20 times before the issue occurs).
If you change line 43 of ContentView.swift to
modelContext.autosaveEnabled = false
and repeat the same steps above, the app will not crash and no ParentItems will go missing.
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 isModified = false
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 */
newParentItem.childItems = newChildItems
Modifying ChildItem
let firstChildItem = parentItem.childItems
.sorted(by: { $0.index < $1.index }).first
if
let firstChildItem,
!firstChildItem.isModified
{
firstChildItem.isModified = true
}
0
0
22