{"record":{"id":"a0d6995f3af8fa76","repo":"Hmbown/CodeWhale","slug":"native-accessibility-helper-needs-a-built-app-or-xcode","errorCode":null,"errorMessage":"native accessibility helper needs a built app or Xcode Command Line Tools: ${r.stderr}","messagePattern":"native accessibility helper needs a built app or Xcode Command Line Tools: (.+?)","errorType":"exception","errorClass":"ExecError","httpStatus":null,"severity":"error","filePath":"crates/tui/plugins/computer-use/src/backends/darwin.mjs","lineNumber":253,"sourceCode":"      if (fs.existsSync(packaged)) helper = packaged;\n    }\n    // A source checkout (plugin installs in other hosts) self-compiles an\n    // unsigned helper, which has no TCC grant. Prefer the installed app's\n    // signed helper so accessibility and screen-recording grants carry over.\n    if (!helper || !fs.existsSync(helper)) {\n      const installed = path.join(os.homedir(), \"Applications\", \"Codewhale Computer Use.app\", \"Contents\", \"MacOS\", \"accessibility\");\n      if (fs.existsSync(installed)) helper = installed;\n    }\n    if (!helper || !fs.existsSync(helper)) {\n      const source = fileURLToPath(new URL(\"./darwin-accessibility.m\", import.meta.url));\n      const hash = crypto.createHash(\"sha256\").update(fs.readFileSync(source)).update(fs.readFileSync(new URL(\"./darwin-recording.h\", import.meta.url))).update(fs.readFileSync(new URL(\"./darwin-ocr.h\", import.meta.url))).digest(\"hex\").slice(0, 16);\n      const dir = path.join(os.homedir(), \".codewhale-cu\", \"bin\");\n      fs.mkdirSync(dir, { recursive: true, mode: 0o700 });\n      helper = path.join(dir, `accessibility-${hash}`);\n      if (!fs.existsSync(helper)) {\n        const tmp = `${helper}-${process.pid}`;\n        const r = await runL(\"clang\", [\"-fobjc-arc\", \"-Os\", \"-framework\", \"Cocoa\", \"-framework\", \"ApplicationServices\", \"-framework\", \"ScreenCaptureKit\", \"-framework\", \"AVFoundation\", \"-framework\", \"CoreMedia\", \"-framework\", \"Vision\", source, \"-o\", tmp], { timeoutMs: 60_000 });\n        if (r.code !== 0) throw new ExecError(`native accessibility helper needs a built app or Xcode Command Line Tools: ${r.stderr}`, r);\n        fs.renameSync(tmp, helper);\n      }\n    }\n    return helper;\n  }\n\n  function requireFocusControl() {\n    if (!state.foregroundInput) throw Object.assign(new ExecError(\"This action would take keyboard focus and was not sent in background mode. Use an accessibility action, browser control, or a separate computer.\"), { code: \"background_focus_required\" });\n  }\n\n  async function native(tool, args = {}) {\n    // Window-addressed events still borrow keyboard focus. Block before even\n    // starting an older installed helper, including the app-scoped fallback.\n    if ([\"bg_pointer\", \"bg_key\"].includes(tool) || (tool === \"pointer_sequence\" && args.app_scoped)) requireFocusControl();\n    // Every resolved target (element center or screen point) is where the\n    // action lands; tracking it here means the preview cursor follows element\n    // actions, not just raw pointer events.\n    if (tool === \"type\" && !state.foregroundInput && (await native(\"input_capabilities\"))?.background_focus_guard !== 1) {","sourceCodeStart":235,"sourceCodeEnd":271,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/plugins/computer-use/src/backends/darwin.mjs#L235-L271","documentation":"The macOS computer-use backend compiles a native Objective-C accessibility helper on demand, caching it under ~/.codewhale-cu/bin. When no pre-built app bundle provides the helper and invoking `clang` to build it fails, this error is thrown with clang's stderr. It means the machine cannot compile the helper because the Xcode Command Line Tools are missing or broken.","triggerScenarios":"nativeHelper() is called (first use of any native input/capture tool), no cached helper exists at ~/.codewhale-cu/bin/accessibility-<hash>, and the `clang -fobjc-arc ... -o <tmp>` compile exits non-zero (60s timeout or compile/link failure).","commonSituations":"Fresh macOS installs without Xcode Command Line Tools; running after an Xcode upgrade that invalidates the toolchain; `xcode-select` pointing at a bare Xcode.app requiring license acceptance; PATH lacking clang (no developer directory selected); a corrupted partial build left in the cache dir from a timed-out build.","solutions":["Install or repair the toolchain: run `xcode-select --install` and accept the license with `sudo xcode-select --license`.","Verify clang works: `xcode-select -p` and `clang --version` must succeed.","If Xcode is installed, ensure `xcode-select -s /Applications/Xcode.app/Contents/Developer` points at it and Xcode has finished its first-run component install.","Clear a corrupt cached/partial helper: remove ~/.codewhale-cu/bin/accessibility-* and retry.","As a fallback, ship or point the backend at a pre-built helper app so clang compilation is never needed."],"exampleFix":"// before (shell)\nnative(\"click\", ...)\n// error: native accessibility helper needs a built app or Xcode Command Line Tools: clang: error: no developer tools found\n\n// after (shell, one-time setup)\nxcode-select --install && clang --version","handlingStrategy":"fallback","validationCode":"const { execSync } = require('child_process');\nfunction clangAvailable() {\n  try { execSync('clang --version', { stdio: 'pipe' }); return true; } catch { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await startComputerUse();\n} catch (e) {\n  if (String(e.message).includes('needs a built app or Xcode Command Line Tools')) {\n    console.error('Install toolchain: xcode-select --install');\n  }\n  throw e;\n}","preventionTips":["Provision macOS runners with Xcode Command Line Tools before launching automation.","Check `xcode-select -p` and `clang --version` in environment setup/CI preflight.","Ship a pre-built helper app to avoid on-machine compilation entirely.","Clear ~/.codewhale-cu/bin after toolchain upgrades so stale builds are never reused."],"tags":["macos","missing-toolchain","compilation","accessibility"],"backgroundTag":"missing-dependency","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"}