{"record":{"id":"d3466f4c11104d95","repo":"stablyai/orca","slug":"emulator-no-active-d3466f","errorCode":"emulator_no_active","errorMessage":"iOS simulator ${udid} is not active for this worktree (active: ${session.deviceUdid}); attach the requested simulator first.","messagePattern":"iOS simulator (.+?) is not active for this worktree \\(active: (.+?)\\); attach the requested simulator first\\.","errorType":"exception","errorClass":"EmulatorError","httpStatus":null,"severity":"error","filePath":"src/main/emulator/emulator-bridge.ts","lineNumber":217,"sourceCode":"    const { backend, device } = await this.resolveTarget(opts)\n    return backend.exec(device, command)\n  }\n\n  async accessibilityTree(opts?: EmulatorTargetOpts): Promise<unknown> {\n    return this.runCapability('accessibilityTree', opts, async (backend, device) => {\n      if (backend.kind !== 'ios') {\n        return backend.accessibilityTree!(device)\n      }\n      const udid = await backend.resolveDeviceId(device)\n      const worktreeId = opts?.worktreeId\n      // Fall back to the udid-keyed session so an explicit --device read works\n      // from a worktree with no active emulator (matching tap/type reachability);\n      // sessions are stored once per udid, so both lookups hit the same state.\n      const session =\n        (worktreeId ? this.getActiveForWorktree(worktreeId) : null) ??\n        this.sessionRegistry.getSession(udid)\n      if (worktreeId && session && session.deviceUdid !== udid) {\n        throw new EmulatorError(\n          'emulator_no_active',\n          `iOS simulator ${udid} is not active for this worktree (active: ${session.deviceUdid}); attach the requested simulator first.`\n        )\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> {","sourceCodeStart":199,"sourceCodeEnd":235,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/emulator/emulator-bridge.ts#L199-L235","documentation":"accessibilityTree() resolved a udid that differs from the device the worktree currently has attached. It is a guard so a read never silently targets a simulator the user did not select for that worktree.","triggerScenarios":"accessibilityTree({ worktreeId }) is called; getActiveForWorktree(worktreeId) returns a session whose deviceUdid !== the resolved udid (emulator-bridge.ts:216-220). The explicit --device resolves to one simulator while the worktree is bound to another.","commonSituations":"User switched the active emulator in another worktree; a stale --device value was passed; the session registry was repointed to a newly-attached device while old commands still reference the prior udid.","solutions":["Run `orca emulator attach <requested-udid>` for the worktree so the active session matches.","Drop the explicit --device from the call so the worktree's already-active simulator is used.","If the registry is stale, run `orca emulator kill` for the worktree and re-attach the correct device."],"exampleFix":"// before\nawait bridge.accessibilityTree({ worktreeId, device: requestedUdid }) // active != requestedUdid\n\n// after\nawait emulatorAttach({ worktreeId, device: requestedUdid })\nawait bridge.accessibilityTree({ worktreeId })","handlingStrategy":"validation","validationCode":"const active = bridge.getActiveForWorktree(worktreeId)\nif (active && active.deviceUdid !== requestedUdid) { /* attach requestedUdid first or drop --device */ }","typeGuard":"function isEmulatorError(e: unknown, code = 'emulator_no_active'): e is import('./emulator-errors').EmulatorError {\n  return e instanceof Error && (e as any).code === code && e.name === 'EmulatorError'\n}","tryCatchPattern":"try { await bridge.accessibilityTree({ worktreeId, device: udid }) }\ncatch (e) { if (isEmulatorError(e, 'emulator_no_active')) { await emulatorAttach({ worktreeId, device: udid }) } else throw e }","preventionTips":["Do not mix an explicit --device with a worktreeId whose active session differs.","Re-attach after switching the active simulator for a worktree.","Treat the worktree's active session as the source of truth for the device."],"tags":["ios","worktree","session","accessibility"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}