[Desktop] iOS Simulator panel: claude-ios-sim crash-loops in Metal/CoreImage on macOS 27.0 beta — panel stuck on 'Attach a simulator'
Summary
The iOS Simulator panel in the Claude desktop app cannot start its video stream on macOS 27.0 beta. The helper process claude-ios-sim (com.anthropic.claude.ios-sim, bundled at Claude.app/Contents/Helpers/Claude iOS Sim.app) crash-loops with an uncaught NSException (SIGABRT) while initializing a CoreImage CIContext, so the panel stays stuck on the "Attach a simulator so Claude can see your app" placeholder, and the MCP screenshot action fails with "Claude Code iOS Simulator is restarting after a crash."
The attach MCP action reports success and the simulator itself is healthy (apps install, launch, and screenshot fine via xcrun simctl), so this is host-side in the panel's capture/streaming pipeline.
Environment
- Claude desktop app: 1.24012.1
- macOS: 27.0 beta (build 26A5388g), Apple Silicon
- Xcode 26.6, iOS Simulator runtimes 26.5 and 27.0
- Booted device: iPhone 17 Pro (iOS 26.5)
Crash signature
lastExceptionBacktrace from ~/Library/Logs/DiagnosticReports/claude-ios-sim-*.ips (identical across ~6 crashes over one day):
CoreFoundation __exceptionPreprocess
libobjc.A.dylib objc_exception_throw
CoreFoundation -[__NSPlaceholderArray initWithObjects:count:] <- nil object inserted
CoreFoundation +[NSArray arrayWithObjects:count:]
Metal __39-[_MTLDevice recordBinaryArchiveUsage:]_block_invoke
libdispatch _dispatch_once_callout
Metal -[_MTLDevice recordBinaryArchiveUsage:]
Metal -[_MTLBinaryArchive loadFromURL:error:]
Metal -[_MTLBinaryArchive initWithOptions:device:url:error:]
CoreImage +[CIKernelLibrary(Internal) internalBinaryArchiveWithName:device:]
CoreImage CI::PrecompiledUberFunctions::PrecompiledUberFunctions(CI::MetalContext const*)
CoreImage CI::MetalContext::init(id<MTLCommandQueue>, char const*)
CoreImage +[CIContext(Internal) internalContextWithMTLCommandQueue:options:]
CoreImage -[CIContext initWithMTLDevice:options:]
Termination: EXC_CRASH (SIGABRT), abort() called, thrown from __cxa_throw via _objc_terminate.
Looks like Metal's binary-archive usage recording gets a nil while building an NSArray on this OS build — i.e. an OS-beta incompatibility — but the helper turning that into a hard crash-loop (instead of falling back to a software/non-binary-archive CI context or surfacing an error in the panel) makes the whole feature unusable.
Steps to reproduce
- macOS 27.0 beta (26A5388g), Claude desktop 1.24012.1.
- Boot any iOS simulator (
xcrun simctl boot <udid>). - In a Claude Code session, use the iOS Simulator tool:
attachsucceeds and the panel opens. - Panel never streams (stays on the attach placeholder); any
screenshotaction returns "restarting after a crash", and a newclaude-ios-sim-*.ipscrash report appears each time.
What I ruled out
- Simulator/app health:
xcrun simctl io <udid> screenshotand app install/launch all work. - iOS runtime version: same behavior regardless of 26.5 vs 27.0 runtimes (crash is host-side, before any device pixels).
- Metal shader caches: deleting
$(getconf DARWIN_USER_CACHE_DIR)/com.apple.metalandcom.apple.metalfeand killing the helper did not change the signature.
Intermittently, after many helper restarts, one panel window did come up streaming — but new panel instances in the same session still land on the placeholder, so recovery is unreliable.
Expected
Either the panel streams on macOS 27 beta, or the helper catches the CI/Metal init failure and shows an actionable error in the panel instead of crash-looping behind a generic "Attach a simulator" placeholder.
Happy to share full .ips files on request.
Showing cached comments. Read the full discussion on GitHub ↗
5 Comments
Confirming this from a separate session — filed as #80257 before finding this one (closing mine as a dupe of this one).
Same symptoms:
attachreports success every time,screenshotalways returns "Claude Code iOS Simulator is restarting after a crash. Try again in 1s.", andxcrun simctl/xcodebuild build/xcodebuild testwere unaffected throughout — matches your "host-side in the panel's capture/streaming pipeline" conclusion exactly.One data point to add: a full macOS restart (not just the helper/Claude app) did not clear it. After rebooting the Mac entirely and relaunching Claude, the very first
attach/screenshotattempt reproduced the identical crash-loop immediately — no "many helper restarts" needed to reach the bad state, and no intermittent successful stream like you saw. This is consistent with your theory that it's a deterministic OS-beta/Metal incompatibility rather than corrupted cache/process state, since a full reboot clears all of that and it still failed on the first try.Also ruled out on my end before finding this issue: multiple simultaneously-booted simulators, and
Simulator.app(the GUI) not being running — neither was the cause; reproduces with exactly one cleanly booted device andSimulator.appconfirmed running viaps.Confirming on a third machine, with one data point that rules out a whole class of explanations.
Environment: Claude Desktop 1.24012.1, macOS 27.0 beta (26A5388g), Apple M5, Xcode 27.0 beta (27A5209h), iOS 27.0 runtime (24A5370g). Identical crash signature —
-[_MTLDevice recordBinaryArchiveUsage:]→+[NSArray arrayWithObjects:count:]nil insert, reached viaFBSurfaceImageGenerator.image()→-[CIContext initWithOptions:]. 9 crashes in a few minutes. Note this reproduces on M5 / Xcode 27 beta, where #80288 is M4 Pro / Xcode 27 release and this report is Xcode 26.6 — so it's independent of GPU generation and Xcode version.New: this is not a general macOS 27 Metal/CoreImage fault. I built a standalone Swift binary exercising the identical path (
CIContext(options: nil)→createCGImage). It succeeds every time on the same machine, under every condition I could match to the helper:| Condition | Result |
|---|---|
|
CIContext(options: nil)+createCGImage| works ||
CIContext(mtlCommandQueue:)| works || With
CoreSimulator.framework+SimulatorKit.frameworkdlopened first | works || With Metal shader cache (
…/C/com.apple.metal/<gpu>) moved aside | works || Under scrubbed env (
env -i, noTMPDIR/HOME) | works |The fault is specific to the
claude-ios-simprocess, not to CoreImage on this OS. Combined with the reboot test above, that also rules out corrupt shader cache and missing temp dir — the two things triage normally reaches for first.Possible direction: the helper is signed with an empty entitlements dictionary (
codesign -d --entitlements :-returns{}) and the abort is inside Metal's binary-archive path. I couldn't verify whether a missing GPU/Metal entitlement or a nil archive URL is the trigger without re-signing the app, but it may be worth checking.Control plane vs capture plane: with the #80288 symlink workaround applied,
attachsucceeds andtapis delivered correctly to a booted iPhone 17 Pro. Only frame capture crashes.Fourth machine confirming, plus a sandbox lead and one adjacent bug your environment can't hit.
Environment: Claude Desktop 1.24012.1, macOS 27.0 (26A5388g), M4 Pro, Xcode 27.0 beta
27A5228h, iOS 27.0 runtimes 24A5380i and 24A5390f. Identical backtrace throughFBSurfaceImageGenerator.image()→-[CIContext initWithOptions:]→_MTLBinaryArchive loadFromURL:→recordBinaryArchiveUsage:→ nil into+[NSArray arrayWithObjects:count:]. Filed separately as #80288 before finding this one.Combined with @oyeeamir's M5 / Xcode 27 beta
27A5209hand your Xcode 26.6, that's three GPU generations and three Xcode builds with one signature.Additionally ruled out here:
24A5380iand on24A5390f, including on a device created fresh, never booted before.xcode-selectstate — reproduced with it pointing at a stale path and after correcting it.screenshotheadlessly. Since no stream is running, this isn't in the encoder: the H.264/JPEG encoding toggle is a red herring (I burned time on it). Thedispatch_onceframe shows it's one-time Metal init on the connect path, before encoding is consulted.SIGABRTfrom an uncaught ObjC exception with a full in-process backtrace, not an externalSIGKILL.~/Library/Caches/com.apple.metal,com.apple.metalfe, and~/Library/Caches/com.anthropic.claude.ios-sim/com.apple.metalall made no difference.$DARWIN_USER_CACHE_DIR/com.apple.metalalready existed with populated per-GPU subdirs.Possible mechanism. The helper's sandbox profile (
Claude.app/Contents/Resources/claude-ios-sim.sb) is(deny default)and grantsfile-write*to onlyCORESIM_HOME,CORESIM_LOGS,DARWIN_TMPand/private/var/tmp. There's a param for the Darwin temp dir but **none for the Darwin user cache dir, and no rule for~/Library/Caches** — where Metal's shader cache lives. A commenter on #80288 reportsMTLGetShaderCachePathreturning nil when the helper's cache-dirmkdirfails, which fits: CoreImage'sinternalBinaryArchiveWithName:needs that path, gets nil, and nil goes into the array.That would also explain @oyeeamir's standalone-binary result — an unsandboxed process writes the cache fine, so the fault only appears under the helper's confinement. Stated as a hypothesis: I see no sandbox violation reports on disk or in the unified log for this process, so it isn't directly confirmed.
Separate bug, newer Xcode 27 seeds only (26.6 machines won't see it, and @oyeeamir's
27A5209happarently didn't either — so it seems to have landed between27A5209hand27A5228h): FBControlCore loads$DEVELOPER_DIR/Library/PrivateFrameworks/SimulatorKit.framework, but Xcode 27 removed that directory —SimulatorKit,DVTFoundation,DVTDeviceFoundationet al. now live inContents/SharedFrameworks.attachfails outright before any Metal code runs. Local workaround, which does work:Details in #80288. Anyone on a seed with the new layout hits that first and never reaches this crash.
---
Correction (edited): I originally wrote Xcode 27.0 release (not beta). Wrong — it's Xcode 27.0 beta
27A5228h; the bundle had been renamed fromXcode-beta.applocally so the path looked like a release install. The cross-environment point is unchanged, but the correct framing is three different builds, not a release-vs-beta split.Update for anyone landing here: both bugs now have verified one-line workarounds, and the Metal one has a full root-cause analysis in #80472.
Verified on macOS 27.0 beta (26A5388g), M4 Pro, Xcode 27 beta
27A5228h, iOS 27.024A5380i:attach,screenshotandtapall work afterwards. The panel had been 100% broken.Two corrections to what I wrote earlier in this thread, since they'd waste other people's time:
~/Library/Caches/…all failed. It is specifically$(getconf DARWIN_USER_CACHE_DIR)— theC/folder in/var/folders/.... The two are easy to conflate and only the latter works.I also bisected the fix in #80472: of the three directories originally published, only
com.apple.metalis required, and Metal never writes into it — it just has to exist.Confirming on a fifth machine, with one data point the thread doesn't have yet: still reproduces on Claude Desktop 1.24012.9 (thread so far only lists 1.24012.1).
Environment: Claude Desktop 1.24012.9, macOS 27.0 beta (
26A5388g), Apple Silicon (J516s), Xcode 26.6, iPhone 17 Pro (iOS 26.5).NSInvalidArgumentException"attempt to insert nil object from objects[0]" in__39-[_MTLDevice recordBinaryArchiveUsage:]_block_invoke, faulting threadcom.facebook.FBSimulatorControl.BitmapStream. Helper aborts ~1–2 s afterattachreports success; 11 identical.ipsfiles over an hour of crash-looping.PrivateFrameworkspath — only the Metal bug applies on this machine; no symlink workaround needed.sandboxdlogged no file-system denials for the helper — onlyuser-preference-readdenies (kCFPreferencesAnyApplication,com.apple.coresimulator) ~1 s before the abort. If the shader-cachemkdiris being denied, it isn't surfacing as a reported sandbox violation on this build.Info.plistships noCFBundleVersion/CFBundleShortVersionString(crash headers show emptyapp_version/build_version), in case Metal's usage-telemetry array also folds in bundle-version fields.Workaround verified here as well:
Immediately after creating the dir:
attach, live panel streaming, and headlessscreenshotall work, helper stays alive, no new.ips. No app restart needed — the next helper respawn picked it up. Happy to attach the.ipsfiles if useful (stack is byte-for-byte the OP's).