JuliusBrussee/caveman · error
Claude-specific Cave Build execution is unavailable until mo
Error message
Claude-specific Cave Build execution is unavailable until model, reasoning, budget, recovery, and wire selectors are enforced
What it means
Unconditional feature gate at the end of claudeCaveBuildEnv: even for a valid, claude-identified, freshly validated lock, Claude-specific Cave Build execution is not implemented yet — model, reasoning, budget, recovery, and wire selectors are not enforced for Claude. The function always throws once a lock passes all prior checks.
Source
Thrown at packages/cli/src/index.ts:5059
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(
"Cave Build is Pi-specific; refusing to attach its identity to Claude Code execution",
);
}
throw new Error(
"Claude-specific Cave Build execution is unavailable until model, reasoning, budget, recovery, and wire selectors are enforced",
);
}
function firstEnvSecret(env: NodeJS.ProcessEnv, keys: string[]): string | undefined {
for (const key of keys) {
const value = env[key];
if (typeof value === "string" && value.trim()) return value.trim();
}
return undefined;
}
function maybeWarnHermesMissingKey(agent: AgentProfile | undefined, gw = gatewayURL()) {
if (agent?.id !== "hermes") return;
if (wrapMode(gw) === "local") {
if (!firstEnvSecret(process.env, HERMES_LOCAL_UPSTREAM_KEY_VARS)) {
process.stderr.write("caveman: Hermes local wrap has no upstream provider key in env for the local proxy to forward; launching anyway, but provider auth may fail\n");
}View on GitHub (pinned to 27d5a3981a)
Solutions
- Do not create .caveman/agent.lock.json for Claude sessions; remove it before launching
- Wait for a caveman release that enforces Claude selectors (model, reasoning, budget, recovery, wire)
- Use Pi for Cave Build workflows until Claude support ships
Example fix
# before # valid lock with harness.id === "claude" still throws # after rm -f .caveman/agent.lock.json # Claude launches without Cave Build gating claude
Defensive patterns
Strategy: validation
Validate before calling
import { existsSync, readFileSync } from "node:fs";
// the only defense: never reach this path with a valid claude lock
const lockPath = ".caveman/agent.lock.json";
if (existsSync(lockPath)) {
const lock = JSON.parse(readFileSync(lockPath, "utf8"));
if (lock.harness?.id === "claude") throw new Error("Claude Cave Build is not implemented; remove the lock");
} Prevention
- Never pre-create .caveman/agent.lock.json for Claude sessions in CI templates
- Track caveman release notes for Claude Cave Build support
- Use Pi for Cave Build workflows until the selectors ship for Claude
When it happens
Trigger: Any launch path that reaches claudeCaveBuildEnv with a present and fully valid .caveman/agent.lock.json whose harness.id is "claude" — there is no configuration that passes beyond this point.
Common situations: Users assuming Cave Build parity across harnesses; CI environments that pre-create a claude lock file.
Related errors
- Cave Build is Pi-specific; refusing to attach its identity t
- Claude caveman-cloud MCP exists but is not Caveman-journaled
- Claude caveman-cloud MCP changed after setup; refusing to ov
- Cave Build lock exists but caveman-agent checker is unavaila
- Cave Build lock is stale or invalid; refusing Claude launch
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/9e69a05ac4016d0f.
Report an issue: GitHub.