[BUG] Desktop app's iOS Simulator breaks under Xcode 27 (Device Hub)
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Description
The Claude Code desktop app ships an iOS Simulator. It fails whenever xcode-select points at Xcode 27.
Root cause
Xcode 27 removed Simulator.app in favour of the new Device Hub, and moved SimulatorKit.framework from Contents/Developer/Library/PrivateFrameworks/ to Contents/SharedFrameworks/. The bundled tool still hardcodes the old path.
Workaround and its limits
Pointing xcode-select back at a pre-Xcode-27 Xcode.app fixes attach/screenshot/tap, but then the tool's build action fails on any project requiring the Xcode 27 SDK. This can be worked around by using Xcode MCP instead.
So there is currently no single xcode-select configuration where this tool can both drive the simulator and build an Xcode-27-dependent project.
Environment
Claude Code desktop app (macOS) (Version Claude 1.24012.1 (0adcae))
Xcode 27.0 beta 4 and Xcode 26.
What Should Happen?
Expected
The bundled tool should resolve SimulatorKit.framework (and other toolchain paths) dynamically based on the active xcode-select/Xcode version, including the new Device Hub-era Contents/SharedFrameworks/ location for Xcode 27+.
Error Messages/Logs
Error Domain=com.facebook.FBControlCore Code=0 "Attempting to load a file at path '/Applications/Xcode 27.app/Contents/Developer/Library/PrivateFrameworks/SimulatorKit.framework', but it does not exist"
Steps to Reproduce
Run xcode-select -s /Applications/Xcode 27.app/Contents/Developer
And try to use the iOS simulator feature on Claude Code
Claude Model
Sonnet (default)
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
Claude 1.24012.1 (0adcae) 2026-07-21T20:59:53.000Z
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Other
Additional Information
_No response_
3 Comments
Confirmed and fully worked around on:
There are two separate breakages stacked here. Fixing the first only exposes the second.
1. Relocated SimulatorKit framework (pane shows No simulators found)
Xcode 27 moved SimulatorKit.framework:
The helper still looks at the old path. Symlink workaround:
mkdir -p $(xcode-select -p)/Library/PrivateFrameworks
ln -s $(xcode-select -p)/../SharedFrameworks/SimulatorKit.framework $(xcode-select -p)/Library/PrivateFrameworks/SimulatorKit.framework
2. Sandbox starves Metal (pane connects, then black-screens + helper SIGABRT)
After the symlink the pane connects (device name and stream controls appear) but the video is black and drops back to Attach. ~/Library/Logs/DiagnosticReports/claude-ios-sim-*.ips shows a repeated crash:
EXC_CRASH (SIGABRT), process claude-ios-sim
-[_MTLDevice recordBinaryArchiveUsage:]_block_invoke
-> objc_exception_throw -> -[__NSPlaceholderArray initWithObjects:count:]
Root cause is the seatbelt profile Claude.app/Contents/Resources/claude-ios-sim.sb. Under macOS 27 the Metal encode path needs two operations the profile denies:
Adding these two rules makes the live video pane work under Xcode 27:
(allow iokit-set-properties)
(allow file-write* (subpath "<DARWIN_USER_CACHE_DIR>")) ;; e.g. /private/var/folders/xxx/C
The profile header notes the IPC/IOKit set could not be narrowed because the denial log was not readable in the author's dev environment. On a machine that actually exercises the video path the denials are readable, so iokit-set-properties can be scoped to the specific GPU user-client class if that is preferred over the blanket allow.
Suggested proper fix
Confirming this on a second, independent machine. Adding two details the original report doesn't cover: a config where the documented
xcode-selectfallback isn't available at all, and a distinct entry point into the same failure.Environment
/Applications/Xcode-beta.app)Failure
attachfails immediately. Slightly different wrapper text than the original report, same underlying cause:This was hit on a booted, healthy simulator (iPhone 17, iOS 27.0) — so it's not the "no device booted" path.
Verified on disk
Worth noting for anyone triaging: the rest of the toolchain is completely healthy —
xcodebuild,xcrun simctl(list/install/launch/screenshot), the iOS 27.0 runtime andaxeall work normally, and a full app build + install + launch to the simulator succeeded. The only thing broken is the hardcoded framework path, which is what makes the reporter's suggested fix (resolve it dynamically from the active Xcode) look like the whole fix for breakage #1.Also worth flagging separately:
Simulator.appno longer exists anywhere, so any code path that shells out toopen -a Simulatorfails independently of the framework issue. That one reads as a damaged Xcode install and isn't — Device Hub replaced it deliberately. Same root change broke expo/expo#46882 and software-mansion/argent#406.Why the documented workaround doesn't apply here
The suggested fallback is pointing
xcode-selectat a pre-27 Xcode. On this machine only Xcode 27 beta is installed, so there is no older Xcode to point at — the fallback isn't degraded, it's unavailable. Combined with the note already in this thread that no singlexcode-selectsetting can both drive the simulator and build an Xcode-27-SDK project, a single-Xcode machine has no working configuration at all.Scope of what I verified
To be precise about what this comment does and doesn't add: I confirmed the breakage and the on-disk paths above. I did not apply @JaydenBeard's symlink or the
claude-ios-sim.sbsandbox changes, so I can't independently corroborate the Metal/SIGABRT second stage or that the two-step fix resolves it. I worked around the task a different way (drove a physical iPhone over iPhone Mirroring instead), which needed no patching of signed bundles.Given this is closed as
NOT PLANNED: the dynamic-path resolution in the original report would fix stage 1 for every Xcode 27 user, and it's the same one-line-shaped change other tools in the ecosystem shipped within days of the beta. Happy to test a fix on the M5 / macOS 27 / Xcode 27 combination if that's useful.Input injection is a second, separate failure — and it fails silently
On macOS 26.5.2 (25F84) with Xcode 27.0 beta (27A5237l), I worked around the
SimulatorKit.frameworkrelocation and found the pane still can't be driven. Two distinct bugs here, and fixing the path alone won't restore control.Working around the path issue without touching the bundle. The documented symlink fix isn't possible on a current macOS — signed-app-bundle protection refuses it even for root:
Instead I built a symlink mirror of the bundle at
~/.xcode27-shim/Xcode.app, mirroringContents/*andContents/Developer/*and adding the one missing piece:then
launchctl setenv DEVELOPER_DIR ~/.xcode27-shim/Xcode.app/Contents/Developer.xcode-select -phonoursDEVELOPER_DIR, so the helper resolves the framework andxcodebuild -versionstill reports Xcode 27.0 — builds and pane at once.Result: video works, input doesn't.
attachandscreenshotnow work and are genuinely live (status-bar clock advances between captures). Buttapandbuttonare no-ops that report success:Three different targets (app icon, dock, Search pill) plus a hardware button, all unchanged. Before the framework loaded,
tapfailed honestly withNo Legacy HID port found; now it returns a success string instead. That regression matters for agent use specifically — Claude can conclude it verified an interaction it never performed.Clicking in the pane by hand does nothing either, so the pane is view-only under Xcode 27, not just unavailable to the model.
Suggested: resolve
SimulatorKit.frameworkfrom both locations and fix HID/input injection for Xcode 27; either alone leaves the pane unusable. In the meantime, havingtap/buttonreturn an error rather than a success string would prevent silently-false verification.