JuliusBrussee/caveman · error
Cave Build lock exists but caveman-agent checker is unavaila
Error message
Cave Build lock exists but caveman-agent checker is unavailable; refusing Claude launch before model spend
What it means
claudeCaveBuildEnv reads .caveman/agent.lock.json in the project; if a Cave Build lock exists, it must be validated by the external caveman-agent binary before Claude launches (to gate model spend). The checker is located via CAVEMAN_AGENT_BIN or PATH lookup of `caveman-agent`; if neither resolves, launch is refused rather than spending model tokens against an unvalidated lock.
Source
Thrown at packages/cli/src/index.ts:5037
} finally {
cleanupWrapTempDirs();
removeProxySessionMarker(sessionMarker);
}
return { code, proxyStarted, sessionStart, summaryKind };
}
export function claudeCaveBuildEnv(): NodeJS.ProcessEnv {
const lockPath = join(process.cwd(), ".caveman", "agent.lock.json");
let rawBeforeCheck: string;
try {
rawBeforeCheck = readFileSync(lockPath, "utf8");
} catch (error) {
if ((error as NodeJS.ErrnoException).code === "ENOENT") return {};
throw error;
}
const checker = process.env.CAVEMAN_AGENT_BIN || which("caveman-agent");
if (!checker) {
throw new Error("Cave Build lock exists but caveman-agent checker is unavailable; refusing Claude launch before model spend");
}
const invocation = portableInvocation(checker, ["check"]);
const checked = spawnSync(invocation.command, invocation.args, {
cwd: process.cwd(),
env: process.env,
encoding: "utf8",
});
if (checked.error || checked.status !== 0) {
const detail = String(checked.stderr || checked.error?.message || "lock check failed").trim();
throw new Error(`Cave Build lock is stale or invalid; refusing Claude launch before model spend: ${detail}`);
}
const rawAfterCheck = readFileSync(lockPath, "utf8");
if (rawAfterCheck !== rawBeforeCheck) {
throw new Error("Cave Build lock changed during validation; refusing Claude launch before model spend");
}
const lock = JSON.parse(rawAfterCheck) as { harness?: { id?: unknown } };
if (lock.harness?.id !== "claude") {
throw new Error(View on GitHub (pinned to 27d5a3981a)
Solutions
- Run `caveman setup --install` to install the Go binaries including caveman-agent
- Or set CAVEMAN_AGENT_BIN to the absolute path of an existing caveman-agent binary
- If the lock is obsolete, remove .caveman/agent.lock.json and launch again
- Ensure the Go bin directory (e.g. ~/go/bin) is on PATH
Example fix
# before # lock present, checker missing claude # Error: Cave Build lock exists but caveman-agent checker is unavailable # after export CAVEMAN_AGENT_BIN="$HOME/go/bin/caveman-agent" claude
Defensive patterns
Strategy: validation
Validate before calling
import { existsSync } from "node:fs";
import { which } from "caveman";
const lockExists = existsSync(join(process.cwd(), ".caveman", "agent.lock.json"));
if (lockExists && !process.env.CAVEMAN_AGENT_BIN && !which("caveman-agent")) {
throw new Error("install caveman-agent (`caveman setup --install`) or delete the stale lock before launch");
} Try / catch
try {
claudeCaveBuildEnv();
} catch (error) {
if (/checker is unavailable/.test((error as Error).message)) {
// choose one: provision the checker, or drop the lock — then retry launch
process.env.CAVEMAN_AGENT_BIN = "/usr/local/bin/caveman-agent";
claudeCaveBuildEnv();
} else throw error;
} Prevention
- Run `caveman setup --install` before using Cave Build-adjacent flows on a machine
- Set CAVEMAN_AGENT_BIN explicitly in CI where PATH is minimal
- Clean up .caveman/agent.lock.json when archiving or cloning projects
When it happens
Trigger: Starting Claude through the caveman launcher in a project containing .caveman/agent.lock.json while caveman-agent is not installed and CAVEMAN_AGENT_BIN is unset or points nowhere.
Common situations: Project was used with Cave Build on another machine or before a caveman uninstall; PATH lost the Go bin directory after setup; CAVEMAN_AGENT_BIN set to a stale path.
Related errors
- Cave Build lock is stale or invalid; refusing Claude launch
- Cave Build lock changed during validation; refusing Claude l
- Cave Build is Pi-specific; refusing to attach its identity t
- lock disappeared during validation
- cave_stale_lock:registration
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/b5bf7d48a28c0f2a.
Report an issue: GitHub.