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

  1. Do not route Claude launches through the Cave Build-gated path; launch Claude directly instead
  2. Upgrade the CLI to a version where the model/reasoning/budget/recovery/wire selectors are enforced and this gate is lifted
  3. Remove the Cave Build lock if the gate keeps triggering on a leftover lock
  4. 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

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


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)