{"record":{"id":"9db9c337e70ac71c","repo":"JuliusBrussee/caveman","slug":"findagent-target-display-name-target-is-un","errorCode":null,"errorMessage":"${findAgent(target)?.display_name ?? target} is unavailable; repair host installation first","messagePattern":"(.+?) is unavailable; repair host installation first","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/index.ts","lineNumber":8547,"sourceCode":"\nasync function nativeDoctor(argv: string[]) {\n  const fix = argv.includes(\"--fix\");\n  const target = argv.find((arg) => arg !== \"--fix\");\n  if ((target !== \"claude\" && target !== \"codex\" && target !== \"hermes\" && target !== \"gemini\" && target !== \"opencode\" && target !== \"pi\" && target !== \"aider\" && target !== \"generic\") || argv.length !== (fix ? 2 : 1) || (fix && target === \"generic\")) commandUsage(\"doctor <claude|codex|hermes|gemini|opencode|pi|aider|generic> [--fix]\");\n  if (target === \"generic\") {\n    const { host, port } = gatewayHostPort();\n    const result = genericIntegrationStatus(await portListening(host, port));\n    print({ ...result, repair: result.components.shared_runtime ? \"caveman start\" : \"caveman setup --install\", trust: \"no host lifecycle hooks\" });\n    return;\n  }\n  const before = nativeIntegrationStatus(target);\n  let fixResult: \"not_needed\" | \"enabled\" | \"repaired\" | \"recovered\" | undefined;\n  if (fix) {\n    if (!before.available && before.transaction_pending) {\n      withIntegrationLock(target, () => recoverPendingNativeInstallUnlocked(target));\n      fixResult = \"recovered\";\n    } else if (!before.available) {\n      throw new Error(`${findAgent(target)?.display_name ?? target} is unavailable; repair host installation first`);\n    } else if (!before.installed) {\n      enableNative([target]);\n      fixResult = \"enabled\";\n    } else if (before.state === \"installed\") {\n      fixResult = \"not_needed\";\n    } else {\n      repairNativeAgent(target);\n      fixResult = \"repaired\";\n    }\n  }\n  const result = nativeIntegrationStatus(target);\n  print({\n    ...result,\n    repair: result.installed ? `caveman doctor ${target} --fix` : `caveman enable ${target}`,\n    trust: target === \"codex\" && result.installed ? \"review through Codex /hooks\" : \"native host policy\",\n    ...(fixResult ? { fix: { attempted: true, result: fixResult } } : {}),\n  });\n  if (result.state === \"degraded\" || result.state === \"unavailable\") process.exitCode = 1;","sourceCodeStart":8529,"sourceCodeEnd":8565,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/5184b3d11ac6a1acb7d44b9bfaa31698157cff97/packages/cli/src/index.ts#L8529-L8565","documentation":"`caveman doctor <agent> --fix` computes availability via nativeHostProbe, which resolves the agent binary and runs `<bin> --version` with a 3s timeout; 'available' means launchable (binary found AND version probe exits 0). When the host is unavailable and there is no pending transaction to recover, --fix throws this error instead of trying to repair an integration whose host cannot run. The operator must fix the host installation first; doctor without --fix still prints a status report.","triggerScenarios":"`caveman doctor claude|codex|hermes|gemini|opencode|aider --fix` when the agent binary is missing, not executable, crashes on `--version`, or the version probe times out (slow disk, hung wrapper script, sandbox blocking spawn).","commonSituations":"Broken agent install (partial npm uninstall, corrupted binary); a wrapper script that prompts or hangs on `--version`; version-manager shims present but the underlying tool version removed; security software blocking child-process spawn.","solutions":["Verify the probe yourself: run `<agent-binary> --version` and make it exit 0 quickly (that is exactly what caveman executes)","Reinstall or repair the host agent (e.g. `npm install -g @anthropic-ai/claude-code`), remove hanging wrappers from PATH, then rerun `caveman doctor <agent> --fix`","If the binary exists but hangs, replace or fix the wrapper (no prompts, no network on --version); the probe times out at 3 seconds","If the host is intentionally absent, use `caveman disable <agent>` to remove the stale integration instead of --fix"],"exampleFix":"# before: host probe fails\ncaveman doctor claude --fix\n# >> Claude Code is unavailable; repair host installation first\nclaude --version\n# >> zsh: command not found: claude\n\n# after: host repaired\nnpm install -g @anthropic-ai/claude-code && claude --version && caveman doctor claude --fix","handlingStrategy":"validation","validationCode":"// availability == binary found AND `<bin> --version` exits 0 within 3s\nimport { spawnSync } from 'node:child_process';\nconst probe = spawnSync(`${process.env.HOME}/.local/bin/claude`, ['--version'], { timeout: 3000, encoding: 'utf8' });\nif (probe.error || probe.status !== 0) {\n  console.error('host unavailable — fix the binary before `caveman doctor claude --fix`');\n} else {\n  console.log('host ok:', probe.stdout.trim());\n}","typeGuard":null,"tryCatchPattern":"catch (err) { if (err.message.includes('is unavailable; repair host installation first')) { /* fix/reinstall the host agent (make `<bin> --version` exit 0), then rerun with --fix */ } else throw err; }","preventionTips":["Health-check agents with a quick `<bin> --version` before scripted doctor --fix runs","Avoid wrapper scripts that hang or prompt on --version (3s timeout marks the host unavailable)","Keep `caveman doctor <agent>` (no --fix) in CI as a read-only gate; only run --fix where you can repair the host"],"tags":["doctor","fix","host-unavailable","version-probe","environment"],"backgroundTag":"command-not-found","analyzedSha":"5184b3d11ac6a1acb7d44b9bfaa31698157cff97","analyzedAt":"2026-08-18T03:14:35.516Z","contentChangedAt":"2026-08-18T03:14:35.516Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}