JuliusBrussee/caveman · error · Error
Claude-specific Cave Build execution is unavailable until…
Error message
Claude-specific Cave Build execution is unavailable until model, reasoning, budget, recovery, and wire selectors are enforced
What it means
This is a deliberate hard stop: even after the Cave Build lock passes validation for Claude (harness id "claude"), the Claude-specific execution path is not implemented yet. It throws until the model, reasoning, budget, recovery, and wire selectors are enforced for the Claude harness, so no unguarded model spend can occur.
Solutions
- Do not route Claude launches through the Cave Build-gated path; launch Claude directly instead
- Upgrade the CLI to a version where the model/reasoning/budget/recovery/wire selectors are enforced and this gate is lifted
- Remove the Cave Build lock if the gate keeps triggering on a leftover lock
- If you need this feature, track the CLI release that implements the required selector enforcement
Example fix
// before $ caveman-cli launch claude # Cave Build gate active // after $ rm .cave-build.lock $ claude # or launch without the Cave Build gate
Defensive patterns
Strategy: fallback
Validate before calling
import { existsSync, readFileSync } from 'fs';
function caveBuildGateActive(lockPath: string) {
if (!existsSync(lockPath)) return false;
try { return JSON.parse(readFileSync(lockPath, 'utf8'))?.harness?.id === 'claude'; }
catch { return false; }
}
// if gate is active, the Claude path is unimplemented — bypass it Try / catch
if (caveBuildGateActive(lockPath)) {
// Claude-specific Cave Build execution is unavailable; launch Claude directly
spawn('claude', args, { stdio: 'inherit' });
} else {
cli.launchClaude();
} Prevention
- Do not route Claude launches through the Cave Build gate until the feature ships
- Remove claude-id Cave Build locks if you don't need the gate
- Upgrade to a CLI version implementing model/reasoning/budget/recovery/wire selector enforcement
- Keep launch scripts independent of the gated path as a fallback
When it happens
Trigger: Any attempt to launch Claude Code through the Cave Build-gated path once the lock has fully validated (checker passed, lock unchanged, harness.id === "claude") — the function unconditionally throws because the feature is not enabled.
Common situations: A developer/test constructing a claude-id Cave Build lock and expecting the gated launcher to proceed; enabling the Cave Build gate for Claude before the supporting selector enforcement shipped; running an older CLI where the Claude Cave Build path was stubbed out.
Related errors
- Cave Build is Pi-specific; refusing to attach its identity…
- Cave Build lock exists but caveman-agent checker is…
- cave_async_jobs_unavailable
- cave_async_jobs_unavailable
- Cave Build lock changed during validation; refusing Claude…
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/9e69a05ac4016d0f.
Report an issue: GitHub.
Appendix: source
Thrown at packages/cli/src/index.ts:5575
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");
}
return;View on GitHub (pinned to 3ee70a1026)