{"record":{"id":"e9b49b5e8e14bcfd","repo":"Hmbown/CodeWhale","slug":"open-application-first-to-choose-the-preview-app","errorCode":null,"errorMessage":"open_application first to choose the preview app","messagePattern":"open_application first to choose the preview app","errorType":"exception","errorClass":"ExecError","httpStatus":null,"severity":"error","filePath":"crates/tui/plugins/computer-use/src/backends/darwin.mjs","lineNumber":995,"sourceCode":"          } else {\n            t.ocr = { status: \"unavailable\", engine: \"apple_vision\", reason: ocr?.reason ?? \"The native OCR helper needs an update or returned mismatched image dimensions\", blocks: [], raster };\n          }\n        } catch (error) {\n          throwIfAborted();\n          if (error.code === \"cancelled\") throw error;\n          t.ocr = { status: \"unavailable\", engine: \"apple_vision\", reason: error.message, blocks: [], ...(raster ? { raster } : {}) };\n        }\n      }\n      return t;\n    },\n    resolve_element: async ({ app_ref, windowIndex, path: pathArr } = {}) => {\n      const r = await native(\"resolve_element\", { app_ref, windowIndex: windowIndex ?? 0, path: pathArr ?? [] });\n      return { found: !!r?.found, element: r?.element ?? null, reason: r?.reason ?? null };\n    },\n    preview: async ({ enabled = true } = {}) => {\n      state.previewEnabled = enabled;\n      if (!enabled) { stopPreviewLoop(); await quiescePreview(); await native(\"preview_notify\", { enabled: false }); return { enabled: false }; }\n      if (!state.inputApp) throw new ExecError(\"open_application first to choose the preview app\");\n      return updatePreview(true);\n    },\n    screenshot,\n    zoom,\n    left_click: async ({ target, strategy = \"auto\" } = {}) => {\n      if (target?.type !== \"element\" || strategy === \"event\" || strategy === \"app\") return pointerClick(\"left\", target?.x, target?.y, 1, strategy);\n      if (![\"auto\", \"a11y\"].includes(strategy)) throw new ExecError(`strategy must be auto, a11y, app or event (got ${JSON.stringify(strategy)})`);\n      try {\n        assertBoundElement(target);\n        if ((await native(\"input_capabilities\"))?.element_identity !== 1) throw new ExecError(\"native helper needs an update for element identity validation\");\n        const semantic = [\"AXTextField\", \"AXTextArea\", \"AXComboBox\", \"AXRow\", \"AXCell\", \"AXMenuItem\"].includes(target.role);\n        if (semantic) await requireBackgroundActions();\n        const receipt = await native(semantic ? \"click_element\" : \"perform_action\", { target, action: \"AXPress\" });\n        if (!receipt?.action_sent) throw new ExecError(\"element press was not acknowledged\");\n        return { ...receipt, action: receipt.action ?? \"AXPress\", strategy: \"a11y\", pointer_moved: false,\n          element: { role: target.role, label: target.label ?? null }, verified: receipt.verified ?? false, verification_required: \"observation\" };\n      } catch (error) {\n        // An AX frame can cover other controls. Never turn a refused or","sourceCodeStart":977,"sourceCodeEnd":1013,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/plugins/computer-use/src/backends/darwin.mjs#L977-L1013","documentation":"Thrown when enabling live preview (preview({enabled:true})) in the macOS backend before any target application has been chosen. The preview loop renders through a dedicated preview app that open_application establishes (stored in state.inputApp); without it there is nothing to attach the preview surface to. The backend requires that ordering rather than silently picking an app.","triggerScenarios":"Calling preview() or preview({enabled:true}) as the first action in a session, or after the preview app was never opened, instead of calling open_application first.","commonSituations":"Scripts that enable preview at startup before selecting a target app; sessions where an earlier error aborted open_application so state.inputApp was never set.","solutions":["Call open_application (with the target app name/pid) before enabling preview.","If preview should be off, call preview({enabled:false}) — that path is allowed and just notifies the helper.","Check for an earlier thrown error that prevented open_application from completing."],"exampleFix":"// before\nconst session = createBackend();\nawait session.preview(); // no app chosen yet\n// after\nconst session = createBackend();\nawait session.open_application({ name: 'Finder' });\nawait session.preview();","handlingStrategy":"validation","validationCode":"if (!session.inputApp) {\n  await session.open_application({ name: targetAppName });\n}\nawait session.preview();","typeGuard":"null","tryCatchPattern":"try {\n  await session.preview();\n} catch (e) {\n  if (String(e.message).includes('open_application first')) {\n    await session.open_application({ name: 'Finder' });\n    await session.preview();\n  } else throw e;\n}","preventionTips":["Treat open_application as step one of every session that uses preview.","Wrap session setup in a helper that enforces call order.","Check state.inputApp (or track it in your wrapper) before toggling preview."],"tags":["macos","preview","call-order","state"],"backgroundTag":"invalid-state-transition","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T16:17:23.217Z"}