`claude-ios-sim` crashes in a loop on macOS 27: uncaught ObjC exception from `-[_MTLDevice recordBinaryArchiveUsage:]`
Summary
The iOS Simulator panel helper (com.anthropic.claude.ios-sim) aborts immediately
every time it is attached, and keeps restarting and crashing in a loop. The panel
never renders a frame.
The crash is an uncaught Objective-C exception thrown on a dispatch queue inside
Metal, so no @try in the calling frame can catch it and std::terminate fires.
13 crash reports were produced in under 48 hours on a single machine, all from
normal use (calling attach, then screenshot).
Environment
| | |
|---|---|
| macOS | 27.0 (26A428) |
| Hardware | Mac14,2 — Apple M2 |
| Xcode | 27.0 (27A266a) — Release Candidate |
| Simulator runtime | iOS 27.0 |
| Crashing process | claude-ios-sim, bundle com.anthropic.claude.ios-sim |
| Exception | EXC_CRASH (SIGABRT) — Abort trap: 6 |
Note: this reproduces on a clean Xcode 27.0 RC installation. It was originally
observed with Xcode 27 beta 6, and reinstalling Xcode from scratch did not change
anything — so it is not caused by a broken or partial Xcode install.
Stack trace (faulting thread)
libsystem_kernel.dylib __pthread_kill
libsystem_pthread.dylib pthread_kill
libsystem_c.dylib abort
libc++abi.dylib __abort_message
libc++abi.dylib demangling_terminate_handler()
libobjc.A.dylib _objc_terminate()
libc++abi.dylib std::__terminate(void (*)())
libc++abi.dylib __cxxabiv1::failed_throw(__cxxabiv1::__cxa_exception*)
libc++abi.dylib __cxa_throw
libobjc.A.dylib objc_exception_throw
CoreFoundation -[__NSPlaceholderArray initWithObjects:count:]
CoreFoundation +[NSArray arrayWithObjects:count:]
Metal __39-[_MTLDevice recordBinaryArchiveUsage:]_block_invoke
libdispatch.dylib _dispatch_client_callout
Analysis
-[_MTLDevice recordBinaryArchiveUsage:] schedules a block that builds an NSArray
via +[NSArray arrayWithObjects:count:]. One of the elements is nil, so-[__NSPlaceholderArray initWithObjects:count:] raises NSInvalidArgumentException.
Because the throw happens inside a block invoked through _dispatch_client_callout,
it unwinds past any exception handling the caller may have installed, reaching_objc_terminate() and aborting the process.
The faulty array construction is inside Metal.framework (Apple code), but it is
reached only through claude-ios-sim's use of Metal — presumably the video pipeline
that streams simulator frames into the panel. Four of the five most recent reports
show this exact Metal frame; the fifth has the identical terminate/abort chain with
partial symbolication.
Impact
The simulator panel is unusable on this configuration. Everything else works, so the
workaround is to drive the simulator entirely through simctl:
xcrun simctl io <udid> screenshot out.png
xcrun simctl install / launch / spawn defaults write ...
This covers build, install, launch, screenshots, taps and preference injection. What
is lost is manual device rotation and complex gestures (pinch, long drags), which
have no simctl equivalent.
Suggested fix
Two independent mitigations, either of which would stop the abort:
- Avoid the trigger — skip or disable Metal binary archive usage recording in the
frame-capture path (e.g. do not attach a MTLBinaryArchive to the pipeline
descriptor), so recordBinaryArchiveUsage: is never reached.
- Contain the throw — wrap the Metal calls that can schedule this block in
@try/@catch, and/or install an uncaught-exception handler in the helper so a
single bad frame degrades the panel instead of killing the process and putting it
in a restart loop.
The restart loop is worth addressing on its own: even if the underlying Metal bug is
Apple's to fix, a helper that aborts and relaunches indefinitely produces dozens of
crash reports and never surfaces a usable error to the user.
Reproduction
- macOS 27.0, Xcode 27.0 RC, at least one booted iOS 27 simulator.
- Attach the simulator panel from Claude Code.
- Request a screenshot.
Expected: the panel renders the simulator.
Actual: claude-ios-sim aborts; retrying reproduces the crash every time.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗