Skip to content

iOS: avoid a SwiftData trap in the stable-id backfill on iOS 27 - #54

Merged
roznet merged 1 commit into
mainfrom
fix/ios27-backfill-crash
Oct 18, 2026
Merged

roznet merged 1 commit into
mainfrom
fix/ios27-backfill-crash

Conversation

@roznet

@roznet roznet commented Oct 18, 2026

Copy link
Copy Markdown
Owner

Problem

A user reported the app crashing immediately at launch on their iPad. The App Store crash point shows 1.9 (19) crashing five times in a row on one iPad Air (iPadOS 27.0.1), 0.2 s after launch, all at the same line:

flyfun_formsApp.backfillStableIDs() → StableRecords.backfill<A> → StableRecords.swift:164, an EXC_BREAKPOINT in SwiftData's PersistentModel.graph_keyPathToString while converting the predicate.

The fetch used #Predicate { $0.uuid == nil } inside a function generic over StableRecord, so the keypath goes through the protocol requirement rather than a concrete model's stored property.

Fix

Fetch each type without a predicate and filter uuid == nil in memory. Record counts are small, and the behaviour is otherwise unchanged.

Testing

  • A Release build of the old code crashed once on the iOS 27.0 simulator with the same stack.
  • Not deterministic: four later launches of the old code (Debug ×2, Release ×2, fresh installs) did not crash, and launching it on a real iOS 27 device didn't crash either. So no test reliably reproduces the crash.
  • With the fix: the Release build launches to the sign-in screen on the iOS 27 simulator; the full unit target passes on iOS 27 (262 tests).
  • Real confirmation needs the affected user on a TestFlight build.

🤖 Generated with Claude Code

The backfill fetched with `#Predicate { $0.uuid == nil }` inside a function
generic over `StableRecord`. On iOS 27, SwiftData can trap converting that
keypath through the protocol requirement: an App Store crash point shows 1.9
(19) crashing at launch five times in a row on one iPad (iPadOS 27.0.1), and
a Release build crashed the same way once on the iOS 27.0 simulator. It is
not deterministic: later Debug and Release launches of the same code did not
crash. Filter in memory instead, which takes the keypath conversion out of
the launch path entirely.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@claude

claude Bot commented Oct 18, 2026

Copy link
Copy Markdown

Code Review

Reviewed the one-line change in StableRecords.backfill, which replaces the #Predicate { $0.uuid == nil } fetch with an unfiltered fetch plus an in-memory filter. It sidesteps the SwiftData keypath trap on iOS 27, the behaviour is unchanged, and there are no CloudKit, privacy or localisation implications. No issues found.

One non-blocking note: the crash did not reproduce reliably, so confirm the fix on a TestFlight build with the affected user, as the PR description already says.

🤖 Generated with Claude Code

@roznet
roznet merged commit 9cfa7c8 into main Oct 18, 2026
3 checks passed
@roznet
roznet deleted the fix/ios27-backfill-crash branch October 18, 2026 16:18
roznet added a commit that referenced this pull request Oct 18, 2026
…gn doc

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant