{"record":{"id":"951e2da664b1f1e7","repo":"JuliusBrussee/caveman","slug":"caveman-proxy-probe-version-lacks-current-nativ","errorCode":null,"errorMessage":"caveman-proxy ${probe.version} lacks current native_runtime_v1 capability; run \\`caveman setup --install\\`","messagePattern":"caveman-proxy (.+?) lacks current native_runtime_v1 capability; run \\\\`caveman setup --install\\\\`","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cli/src/index.ts","lineNumber":6015,"sourceCode":"  if (!bytes || bytes.length === 0) return {};\n  const parsed = JSON.parse(bytes.toString(\"utf8\"));\n  if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) throw new Error(`${path} is not a JSON object`);\n  return parsed as Record<string, unknown>;\n}\n\nfunction nativeMcpBinaryRequired(): string {\n  const compatible = probeMcpBinary();\n  if (!compatible) throw new Error(\"caveman-mcp not found; run `caveman setup --install`\");\n  if (!compatible.probe.current) throw new Error(`caveman-mcp ${compatible.probe.version} lacks current mcp_recovery capability; run \\`caveman setup --install\\``);\n  return compatible.binary;\n}\n\nfunction nativeProxyBinaryRequired(gw: string): void {\n  if (wrapMode(gw) !== \"local\") return;\n  const binary = resolveGoBin(\"caveman-proxy\", \"CAVEMAN_PROXY_BIN\");\n  if (!binary) throw new Error(\"caveman-proxy not found; run `caveman setup --install`\");\n  const probe = probeVersionedBinary(binary, \"native_runtime_v1\");\n  if (!probe.current) throw new Error(`caveman-proxy ${probe.version} lacks current native_runtime_v1 capability; run \\`caveman setup --install\\``);\n}\n\nfunction nativeHostProbe(agent: AgentProfile): { binary: string | null; launchable: boolean; version: string | null; error: string | null } {\n  const binary = which(binOf(agent));\n  if (!binary) return { binary: null, launchable: false, version: null, error: \"binary_not_found\" };\n  try {\n    const invocation = portableInvocation(binary, [\"--version\"]);\n    const out = spawnSync(invocation.command, invocation.args, { encoding: \"utf8\", timeout: 3000 });\n    if (out.error) return { binary, launchable: false, version: null, error: boundedHookString(out.error.message, 240) ?? \"version_probe_failed\" };\n    const value = `${out.stdout ?? \"\"} ${out.stderr ?? \"\"}`.trim();\n    if (out.status !== 0) return { binary, launchable: false, version: value ? value.slice(0, 160) : null, error: `version_probe_exit_${out.status ?? \"unknown\"}` };\n    return { binary, launchable: true, version: value ? value.slice(0, 160) : null, error: null };\n  } catch {\n    return { binary, launchable: false, version: null, error: \"version_probe_failed\" };\n  }\n}\n\nfunction detectedAgentVersion(agent: AgentProfile): string | null { return nativeHostProbe(agent).version; }","sourceCodeStart":5997,"sourceCodeEnd":6033,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/packages/cli/src/index.ts#L5997-L6033","documentation":"Thrown by nativeProxyBinaryRequired() when Caveman runs in 'local' wrap mode: it resolves the caveman-proxy Go binary (via resolveGoBin/CAVEMAN_PROXY_BIN) and probes it with probeVersionedBinary(binary, \"native_runtime_v1\"). If the installed binary's version does not satisfy the native_runtime_v1 capability, the proxy is too old to host native integrations and the install aborts before touching any agent config.","triggerScenarios":"Any native agent-integration install path (e.g. `caveman setup`, enabling claude/gemini/opencode/aider/codex/hermes native routing) while wrapMode(gateway) === \"local\" and the resolved caveman-proxy binary reports a version lacking native_runtime_v1 (old build on PATH, or CAVEMAN_PROXY_BIN pointing at a stale binary).","commonSituations":"Upgraded the caveman CLI without reinstalling Go binaries; CAVEMAN_PROXY_BIN env var pinned to an old checkout/build; a second caveman install earlier on PATH; partial `caveman setup --install` that failed mid-way.","solutions":["Run `caveman setup --install` to rebuild/reinstall caveman-proxy at the expected version","Check `echo $CAVEMAN_PROXY_BIN` and `which caveman-proxy`; unset the override or fix PATH so the fresh binary resolves first","Re-run the native integration command that failed after the install completes","If install fails, verify the Go toolchain is present (the proxy is built from source) and retry `caveman setup --install`"],"exampleFix":"# before\n$ caveman native install claude\nError: caveman-proxy v0.3.1 lacks current native_runtime_v1 capability; run `caveman setup --install`\n\n# after\n$ caveman setup --install\n$ caveman native install claude   # succeeds","handlingStrategy":"validation","validationCode":"// Before native install, probe the proxy binary the same way the CLI does\nimport { spawnSync } from \"node:child_process\";\nfunction proxyHasNativeRuntime(bin: string): boolean {\n  const out = spawnSync(bin, [\"--capabilities\"], { encoding: \"utf8\", timeout: 3000 });\n  return !out.error && `${out.stdout}${out.stderr}`.includes(\"native_runtime_v1\");\n}\nif (!proxyHasNativeRuntime(process.env.CAVEMAN_PROXY_BIN ?? \"caveman-proxy\")) {\n  spawnSync(\"caveman\", [\"setup\", \"--install\"], { stdio: \"inherit\" });\n}","typeGuard":null,"tryCatchPattern":"try {\n  runNativeInstall();\n} catch (e) {\n  if (e instanceof Error && /lacks current native_runtime_v1/.test(e.message)) {\n    await installThenRetry(); // caveman setup --install, then retry once\n  } else throw e;\n}","preventionTips":["Run `caveman setup --install` immediately after upgrading the caveman CLI so the Go binaries stay in sync","Do not pin CAVEMAN_PROXY_BIN to a checkout; let the managed install own the binary location","In automation, probe the proxy capability before invoking integration installs"],"tags":["binary","version","installation","proxy","capability-check"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}