stablyai/orca · error · EmulatorError

emulator_not_macos

emulator_not_macos

Error message

iOS Simulator requires macOS with Xcode Command Line Tools.

What it means

ensureSimulatorBooted guards on platform() === 'darwin' and refuses on Linux/Windows because the iOS Simulator depends on CoreSimulator plus Xcode Command Line Tools. The check runs before any simctl invocation.

Source

Thrown at src/main/emulator/simctl-simulator-devices.ts:126

  try {
    const raw = await execServeSimCommand(serveSimExecutable, ['--list', '-q'], {
      json: true,
      timeoutMs: 10_000
    })
    if (raw && typeof raw === 'object') {
      const device = (raw as { device?: unknown }).device
      if (typeof device === 'string' && device.toLowerCase().includes(deviceOrName.toLowerCase())) {
        return device
      }
    }
  } catch {}
  return deviceOrName
}

export async function ensureSimulatorBooted(udid: string): Promise<void> {
  if (platform() !== 'darwin') {
    throw new EmulatorError(
      'emulator_not_macos',
      'iOS Simulator requires macOS with Xcode Command Line Tools.'
    )
  }
  const devices = await listSimulatorDevices()
  const device = devices.find((candidate) => candidate.udid === udid)
  if (!device) {
    throw new EmulatorError(
      'emulator_device_not_found',
      `Simulator ${udid} not found. Create one via Xcode > Window > Devices and Simulators.`
    )
  }
  if (device.state === 'Booted') {
    return
  }

  try {
    await new Promise<void>((resolve, reject) => {

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Run on macOS with Xcode + Command Line Tools installed.
  2. Use the Android backend on Linux/Windows hosts.
  3. Gate iOS emulator features behind a macOS host check in your own code.

Example fix

// before
await ensureSimulatorBooted(udid) // on Linux -> emulator_not_macos

// after
import { platform } from 'node:os'
if (platform() === 'darwin') await ensureSimulatorBooted(udid)
else await androidBackend.startSession(serial)
Defensive patterns

Strategy: validation

Validate before calling

import { platform } from 'node:os'
if (platform() !== 'darwin') { /* route to android or surface 'macOS required' */ }

Type guard

function isEmulatorError(e: unknown, code = 'emulator_not_macos'): e is import('./emulator-errors').EmulatorError {
  return e instanceof Error && (e as any).code === code && e.name === 'EmulatorError'
}

Try / catch

try { await ensureSimulatorBooted(udid) }
catch (e) { if (isEmulatorError(e, 'emulator_not_macos')) { /* use android backend */ } else throw e }

Prevention

When it happens

Trigger: ensureSimulatorBooted(udid) is called when platform() !== 'darwin' (simctl-simulator-devices.ts:125-129).

Common situations: Running the iOS emulator backend on Linux/Windows; CI on non-mac runners; platform() reporting unexpectedly due to a containerized/WSL environment.

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/e6dc00a78200f099. Report an issue: GitHub.