stablyai/orca · error · EmulatorError
emulator_unsupported
emulator_unsupported
Error message
${capability} is not supported by the ${backend.kind} emulator backend What it means
runCapability rejects when the resolved backend's capabilities map marks the requested verb false. The iOS backend disables install/launch/permissions/logcat (only accessibilityTree is true); the Android backend enables all five. This turns an impossible verb into a clear error instead of a silent no-op.
Source
Thrown at src/main/emulator/emulator-bridge.ts:238
)
}
// Heal sessions registered without an axUrl (parse-time derivation only
// covers fresh --detach output) by deriving it from the mjpeg stream URL.
const axUrl = session?.axUrl ?? deriveAxUrlFromStreamUrl(session?.streamUrl)
return backend.accessibilityTree!(udid, axUrl)
})
}
// Runs a capability-gated verb against the resolved target, rejecting backends
// that do not advertise the capability (e.g. install/logcat on iOS).
async runCapability<T>(
capability: keyof EmulatorBackendCapabilities,
opts: EmulatorTargetOpts | undefined,
run: (backend: EmulatorBackend, deviceId: string) => Promise<T>
): Promise<T> {
const { backend, device } = await this.resolveTarget(opts)
if (!backend.capabilities[capability]) {
throw new EmulatorError(
'emulator_unsupported',
`${capability} is not supported by the ${backend.kind} emulator backend`
)
}
return run(backend, device)
}
async startHelperForDevice(device: string): Promise<EmulatorSessionInfo> {
const backend = await this.backendForDevice(device)
return backend.startSession(device)
}
async kill(device?: string, worktreeId?: string): Promise<string> {
const { backend, udid } = await this.resolveStopTarget(device, worktreeId)
await backend.stopHelperForDevice(udid, {
helperPid: this.sessionRegistry.getSession(udid)?.pid,
includeOrphaned: true
})View on GitHub (pinned to 1136503c6a)
Solutions
- Target an Android emulator/device (serial or AVD name) for install/logcat/launch/permissions.
- Check `backend.capabilities[capability]` before invoking the verb and skip/warn on unsupported backends.
- Pass an explicit `--device <android-serial>` so resolveTarget routes to the Android backend.
Example fix
// before
await bridge.runCapability('logcat', { device: iosUdid }, run) // throws emulator_unsupported
// after
const { backend } = await bridge.resolveTarget({ device })
if (backend.capabilities.logcat) {
await bridge.runCapability('logcat', { device }, run)
} Defensive patterns
Strategy: validation
Validate before calling
const { backend } = await bridge.resolveTarget(opts)
if (!backend.capabilities[capability]) { /* skip or route to android */ } Type guard
function isEmulatorError(e: unknown, code = 'emulator_unsupported'): e is import('./emulator-errors').EmulatorError {
return e instanceof Error && (e as any).code === code && e.name === 'EmulatorError'
} Try / catch
try { await bridge.runCapability('logcat', opts, run) }
catch (e) { if (isEmulatorError(e, 'emulator_unsupported')) { /* pick an android device */ } else throw e } Prevention
- Remember the iOS backend only supports accessibilityTree; install/logcat/launch/permissions are Android-only.
- Check backend.capabilities before scripting cross-platform emulator flows.
- Use explicit device selectors to avoid accidental iOS routing.
When it happens
Trigger: bridge routes installApp/launchApp/setPermission/logcat (or accessibilityTree) through runCapability; backend.capabilities[capability] is false at emulator-bridge.ts:237. Concrete case: calling install/logcat when backend.kind === 'ios'.
Common situations: Running an Android-only command (logcat, install, permissions) against an iOS simulator; a device selector matched the iOS backend when an Android serial was intended; a recipe/script assumes the full Android capability set on every backend.
Related errors
- pairing keychain presence record is invalid
- unsupported_capability
- emulator_error
- emulator_device_not_found
- emulator_helper_failed
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/6337af6cc612b8f6.
Report an issue: GitHub.