stablyai/orca · error · EmulatorError
emulator_helper_failed
emulator_helper_failed
Error message
serve-sim did not return stream endpoints.
What it means
parseServeSimDetachedSession requires serve-sim's `--detach` output to be a JSON object. A null/non-object payload means the helper invocation produced nothing usable, so no stream endpoints can be derived.
Source
Thrown at src/main/emulator/serve-sim-detached-session.ts:24
const MJPEG_STREAM_SUFFIX = '/stream.mjpeg'
function streamUrlFromServeSimUrl(url: string): string {
return url.endsWith(MJPEG_STREAM_SUFFIX) ? url : `${url.replace(/\/$/, '')}${MJPEG_STREAM_SUFFIX}`
}
// Derive the helper /ax endpoint by swapping the mjpeg stream suffix. Guarded to
// that suffix so a non-mjpeg stream URL never fabricates a bogus /ax endpoint.
export function deriveAxUrlFromStreamUrl(streamUrl: string | undefined): string | undefined {
if (!streamUrl || !streamUrl.endsWith(MJPEG_STREAM_SUFFIX)) {
return undefined
}
return `${streamUrl.slice(0, -MJPEG_STREAM_SUFFIX.length)}/ax`
}
export function parseServeSimDetachedSession(raw: unknown, udid: string): EmulatorSessionInfo {
if (!raw || typeof raw !== 'object') {
throw new EmulatorError('emulator_helper_failed', 'serve-sim did not return stream endpoints.')
}
const json = raw as Record<string, unknown>
const wsUrl = typeof json.wsUrl === 'string' ? json.wsUrl : undefined
const streamUrl =
typeof json.streamUrl === 'string'
? json.streamUrl
: typeof json.url === 'string'
? streamUrlFromServeSimUrl(json.url)
: undefined
const info: EmulatorSessionInfo = {
deviceUdid: typeof json.device === 'string' ? json.device : udid,
wsUrl: wsUrl ?? '',
streamUrl: streamUrl ?? '',
axUrl: typeof json.axUrl === 'string' ? json.axUrl : deriveAxUrlFromStreamUrl(streamUrl)
}
if (!info.streamUrl || !info.wsUrl) {
throw new EmulatorError('emulator_helper_failed', 'serve-sim did not return stream endpoints.')
}View on GitHub (pinned to 1136503c6a)
Solutions
- Verify the serve-sim executable resolves and runs (`serve-sim --version`).
- Re-run `orca emulator attach` after restarting the simulator service.
- Check serve-sim stderr/logs for the startup error that produced non-JSON stdout.
Example fix
// before
const raw = await execServeSim(['--detach', '-q', udid])
parseServeSimDetachedSession(raw, udid) // raw is a string error
// after
const raw = await execServeSim(['--detach', '-q', udid], { json: true })
if (!raw || typeof raw !== 'object') throw new Error('serve-sim --detach produced no JSON')
parseServeSimDetachedSession(raw, udid) Defensive patterns
Strategy: validation
Validate before calling
if (!raw || typeof raw !== 'object') { throw new Error('serve-sim --detach produced no JSON object') } Type guard
function isEmulatorError(e: unknown, code = 'emulator_helper_failed'): e is import('./emulator-errors').EmulatorError {
return e instanceof Error && (e as any).code === code && e.name === 'EmulatorError'
} Try / catch
try { return parseServeSimDetachedSession(raw, udid) }
catch (e) { if (isEmulatorError(e) && /did not return stream endpoints/.test(e.message)) { /* verify serve-sim binary */ } else throw e } Prevention
- Always pass { json: true } to execServeSim for --detach.
- Verify the serve-sim executable runs before attaching.
- Inspect serve-sim stderr when stdout is not JSON.
When it happens
Trigger: execServeSim(['--detach','-q',udid]) returns raw that is falsy or typeof !== 'object' (serve-sim-detached-session.ts:23-24).
Common situations: serve-sim binary missing or broken; it printed an error string to stdout instead of JSON; the helper crashed; a version mismatch changed the --detach output shape.
Related errors
- emulator_error
- [verify-packaged-plugin-resources] invalid ${label} at ${pat
- emulator_helper_failed
- Invalid pet.json: ${error instanceof Error ? error.message :
- Package version is not valid semver: ${baseVersion}
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/9e2325794859077d.
Report an issue: GitHub.