Skip to content

run-ios: "Unable to boot device in current state: Booted" alert when the simulator is already booted #2820

Description

@bryandent

Environment

  • @react-native-community/cli: 20.2.0 (also reproduces on main, latest commit 9013a48 at time of writing)
  • OS: macOS (Apple Silicon)
  • Xcode: stable (not Xcode 27 beta) — Simulator.app present at $(xcode-select -p)/Applications/Simulator.app, so the run-ios code path takes the Simulator.app branch (not the DeviceHub branch added in feat: Support DeviceHub for Xcode 27+ #2806)

Description

Running run-ios against a simulator that is already booted pops a modal alert from Simulator.app reading:

Unable to boot device in current state: Booted

before the build proceeds. The alert must be dismissed manually and it recurs on every re-launch until the simulator is shut down. The build itself still succeeds. A cold first launch (no booted device) is unaffected.

Root cause

In packages/cli-platform-apple/src/commands/runCommand/runOnSimulator.ts, the open Simulator.app --args -CurrentDeviceUDID <udid> call runs unconditionally, before the simulator.state !== 'Booted' guard:

if (fs.existsSync(simulatorApp)) {
  child_process.execFileSync('open', [
    simulatorApp,
    '--args',
    '-CurrentDeviceUDID',
    simulator.udid,
  ]);
} else if (fs.existsSync(deviceHubApp)) {
  ...
}

if (simulator.state !== 'Booted') {
  bootSimulator(simulator);
}

Passing -CurrentDeviceUDID for an already-booted device makes Simulator.app re-attempt a boot of that device, which CoreSimulator rejects with the exact string Unable to boot device in current state: Booted. Simulator.app surfaces that rejection as a modal alert.

The later simulator.state !== 'Booted' guard correctly skips the explicit xcrun simctl boot, but it is too late — the open ... --args -CurrentDeviceUDID call has already provoked the dialog. The DeviceHub branch (Xcode 27+) is unaffected, since it never passes -CurrentDeviceUDID.

Fix

Only pass -CurrentDeviceUDID when the device is not already booted; when it is booted, just bring the running Simulator.app to the foreground. A PR is incoming.

Reproducible Demo

  1. npx react-native run-ios — boots a fresh simulator; no alert.
  2. Leave the simulator booted (don't shut it down).
  3. npx react-native run-ios again → the "Unable to boot device in current state: Booted" modal appears over Simulator.app.
  4. Click OK to dismiss; the build continues normally.
  5. Reproduces on every subsequent run-ios until the simulator is shut down.

Expected: Step 3 should just foreground Simulator.app and install/launch the app — no alert — same as the clean first launch.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions