[BUG] Desktop app's iOS Simulator breaks under Xcode 27 (Device Hub)

Status Fixed / completed
Maintainer reply None cached
Activity 3 comments · opened Jul 22, 2026 · closed Aug 25, 2026

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_

View original on GitHub ↗

3 Comments

JaydenBeard · 2 months ago

Confirmed and fully worked around on:

  • macOS 27.0 beta (build 26A5388g), Apple Silicon
  • Xcode 27 beta (Xcode-beta.app)
  • Claude Desktop 1.24012.9

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:

  • old: Contents/Developer/Library/PrivateFrameworks/SimulatorKit.framework
  • new: Contents/SharedFrameworks/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:

  • iokit-set-properties (GPU/AGX driver writes) -- blocked by (deny default)
  • file-write* into DARWIN_USER_CACHE_DIR (the .../C/... path, where Metal writes its binary-archive / shader cache). The profile only allows writes to DARWIN_TMP (.../T/...), the CoreSimulator dirs, and /private/var/tmp.

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

  1. Resolve SimulatorKit.framework (and any other relocated frameworks) dynamically from the active Xcode instead of the hard-coded Developer/Library/PrivateFrameworks path.
  2. Add the two sandbox allowances above to claude-ios-sim.sb (ideally with file-write* scoped to the Metal cache subpath) so the video encoder works on macOS 27 / Xcode 27.
tonydehnke · 2 months ago

Confirming this on a second, independent machine. Adding two details the original report doesn't cover: a config where the documented xcode-select fallback isn't available at all, and a distinct entry point into the same failure.

Environment

  • Apple M5, macOS 27.0 beta (build 26A5388g)
  • Xcode 27.0 beta, build 27A5228h — the only Xcode installed (/Applications/Xcode-beta.app)
  • Claude Code CLI 2.1.220, Claude Desktop 1.24012.9

Failure

attach fails immediately. Slightly different wrapper text than the original report, same underlying cause:

Could not attach simulator panel: Failed to read the device's state: Simulator framework failed to load:
Error Domain=com.facebook.FBControlCore Code=0 "Attempting to load a file at path
'/Applications/Xcode-beta.app/Contents/Developer/Library/PrivateFrameworks/SimulatorKit.framework',
but it does not exist"

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

Contents/SharedFrameworks/SimulatorKit.framework          EXISTS   <- new location
Contents/Developer/Library/PrivateFrameworks/SimulatorKit.framework   ABSENT
Contents/Applications/Simulator.app                        ABSENT
Contents/Applications/DeviceHub.app                        EXISTS

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 and axe all 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.app no longer exists anywhere, so any code path that shells out to open -a Simulator fails 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-select at 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 single xcode-select setting 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.sb sandbox 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.

Heilemann · 1 month ago

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.framework relocation 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:

$ sudo mkdir -p "/Applications/Xcode-beta.app/Contents/Developer/Library/PrivateFrameworks"
Password:
mkdir: ...: Operation not permitted

Instead I built a symlink mirror of the bundle at ~/.xcode27-shim/Xcode.app, mirroring Contents/* and Contents/Developer/* and adding the one missing piece:

Contents/Developer/Library/PrivateFrameworks/SimulatorKit.framework
  -> ../../../SharedFrameworks/SimulatorKit.framework

then launchctl setenv DEVELOPER_DIR ~/.xcode27-shim/Xcode.app/Contents/Developer. xcode-select -p honours DEVELOPER_DIR, so the helper resolves the framework and xcodebuild -version still reports Xcode 27.0 — builds and pane at once.

Result: video works, input doesn't. attach and screenshot now work and are genuinely live (status-bar clock advances between captures). But tap and button are no-ops that report success:

Tapped at (270, 244) on iPhone 17 Pro Max (04EB63F4-...)   -> screen unchanged
Tapped at (172, 908) ...                                    -> screen unchanged
Pressed LOCK on iPhone 17 Pro Max ...                       -> screen unchanged

Three different targets (app icon, dock, Search pill) plus a hardware button, all unchanged. Before the framework loaded, tap failed honestly with No 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.framework from both locations and fix HID/input injection for Xcode 27; either alone leaves the pane unusable. In the meantime, having tap/button return an error rather than a success string would prevent silently-false verification.