{"record":{"id":"6337af6cc612b8f6","repo":"stablyai/orca","slug":"emulator-unsupported","errorCode":"emulator_unsupported","errorMessage":"${capability} is not supported by the ${backend.kind} emulator backend","messagePattern":"(.+?) is not supported by the (.+?) emulator backend","errorType":"exception","errorClass":"EmulatorError","httpStatus":null,"severity":"error","filePath":"src/main/emulator/emulator-bridge.ts","lineNumber":238,"sourceCode":"        )\n      }\n      // Heal sessions registered without an axUrl (parse-time derivation only\n      // covers fresh --detach output) by deriving it from the mjpeg stream URL.\n      const axUrl = session?.axUrl ?? deriveAxUrlFromStreamUrl(session?.streamUrl)\n      return backend.accessibilityTree!(udid, axUrl)\n    })\n  }\n\n  // Runs a capability-gated verb against the resolved target, rejecting backends\n  // that do not advertise the capability (e.g. install/logcat on iOS).\n  async runCapability<T>(\n    capability: keyof EmulatorBackendCapabilities,\n    opts: EmulatorTargetOpts | undefined,\n    run: (backend: EmulatorBackend, deviceId: string) => Promise<T>\n  ): Promise<T> {\n    const { backend, device } = await this.resolveTarget(opts)\n    if (!backend.capabilities[capability]) {\n      throw new EmulatorError(\n        'emulator_unsupported',\n        `${capability} is not supported by the ${backend.kind} emulator backend`\n      )\n    }\n    return run(backend, device)\n  }\n\n  async startHelperForDevice(device: string): Promise<EmulatorSessionInfo> {\n    const backend = await this.backendForDevice(device)\n    return backend.startSession(device)\n  }\n\n  async kill(device?: string, worktreeId?: string): Promise<string> {\n    const { backend, udid } = await this.resolveStopTarget(device, worktreeId)\n    await backend.stopHelperForDevice(udid, {\n      helperPid: this.sessionRegistry.getSession(udid)?.pid,\n      includeOrphaned: true\n    })","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/emulator/emulator-bridge.ts#L220-L256","documentation":"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.","triggerScenarios":"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'.","commonSituations":"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.","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."],"exampleFix":"// before\nawait bridge.runCapability('logcat', { device: iosUdid }, run) // throws emulator_unsupported\n\n// after\nconst { backend } = await bridge.resolveTarget({ device })\nif (backend.capabilities.logcat) {\n  await bridge.runCapability('logcat', { device }, run)\n}","handlingStrategy":"validation","validationCode":"const { backend } = await bridge.resolveTarget(opts)\nif (!backend.capabilities[capability]) { /* skip or route to android */ }","typeGuard":"function isEmulatorError(e: unknown, code = 'emulator_unsupported'): e is import('./emulator-errors').EmulatorError {\n  return e instanceof Error && (e as any).code === code && e.name === 'EmulatorError'\n}","tryCatchPattern":"try { await bridge.runCapability('logcat', opts, run) }\ncatch (e) { if (isEmulatorError(e, 'emulator_unsupported')) { /* pick an android device */ } else throw e }","preventionTips":["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."],"tags":["capabilities","ios","android","backend"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}