{"record":{"id":"9e2325794859077d","repo":"stablyai/orca","slug":"emulator-helper-failed-9e2325","errorCode":"emulator_helper_failed","errorMessage":"serve-sim did not return stream endpoints.","messagePattern":"serve-sim did not return stream endpoints\\.","errorType":"exception","errorClass":"EmulatorError","httpStatus":null,"severity":"error","filePath":"src/main/emulator/serve-sim-detached-session.ts","lineNumber":24,"sourceCode":"\nconst MJPEG_STREAM_SUFFIX = '/stream.mjpeg'\n\nfunction streamUrlFromServeSimUrl(url: string): string {\n  return url.endsWith(MJPEG_STREAM_SUFFIX) ? url : `${url.replace(/\\/$/, '')}${MJPEG_STREAM_SUFFIX}`\n}\n\n// Derive the helper /ax endpoint by swapping the mjpeg stream suffix. Guarded to\n// that suffix so a non-mjpeg stream URL never fabricates a bogus /ax endpoint.\nexport function deriveAxUrlFromStreamUrl(streamUrl: string | undefined): string | undefined {\n  if (!streamUrl || !streamUrl.endsWith(MJPEG_STREAM_SUFFIX)) {\n    return undefined\n  }\n  return `${streamUrl.slice(0, -MJPEG_STREAM_SUFFIX.length)}/ax`\n}\n\nexport function parseServeSimDetachedSession(raw: unknown, udid: string): EmulatorSessionInfo {\n  if (!raw || typeof raw !== 'object') {\n    throw new EmulatorError('emulator_helper_failed', 'serve-sim did not return stream endpoints.')\n  }\n  const json = raw as Record<string, unknown>\n  const wsUrl = typeof json.wsUrl === 'string' ? json.wsUrl : undefined\n  const streamUrl =\n    typeof json.streamUrl === 'string'\n      ? json.streamUrl\n      : typeof json.url === 'string'\n        ? streamUrlFromServeSimUrl(json.url)\n        : undefined\n  const info: EmulatorSessionInfo = {\n    deviceUdid: typeof json.device === 'string' ? json.device : udid,\n    wsUrl: wsUrl ?? '',\n    streamUrl: streamUrl ?? '',\n    axUrl: typeof json.axUrl === 'string' ? json.axUrl : deriveAxUrlFromStreamUrl(streamUrl)\n  }\n  if (!info.streamUrl || !info.wsUrl) {\n    throw new EmulatorError('emulator_helper_failed', 'serve-sim did not return stream endpoints.')\n  }","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/emulator/serve-sim-detached-session.ts#L6-L42","documentation":"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.","triggerScenarios":"execServeSim(['--detach','-q',udid]) returns raw that is falsy or typeof !== 'object' (serve-sim-detached-session.ts:23-24).","commonSituations":"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.","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."],"exampleFix":"// before\nconst raw = await execServeSim(['--detach', '-q', udid])\nparseServeSimDetachedSession(raw, udid) // raw is a string error\n\n// after\nconst raw = await execServeSim(['--detach', '-q', udid], { json: true })\nif (!raw || typeof raw !== 'object') throw new Error('serve-sim --detach produced no JSON')\nparseServeSimDetachedSession(raw, udid)","handlingStrategy":"validation","validationCode":"if (!raw || typeof raw !== 'object') { throw new Error('serve-sim --detach produced no JSON object') }","typeGuard":"function isEmulatorError(e: unknown, code = 'emulator_helper_failed'): e is import('./emulator-errors').EmulatorError {\n  return e instanceof Error && (e as any).code === code && e.name === 'EmulatorError'\n}","tryCatchPattern":"try { return parseServeSimDetachedSession(raw, udid) }\ncatch (e) { if (isEmulatorError(e) && /did not return stream endpoints/.test(e.message)) { /* verify serve-sim binary */ } else throw e }","preventionTips":["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."],"tags":["ios","serve-sim","json","validation"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}