JuliusBrussee/caveman · error · Error

cave_harness_build_mismatch

cave_harness_build_mismatch

Error message

cave_harness_build_mismatch

What it means

Thrown while preparing a locked harness (packages/agent/src/execution-kernel.ts:76): the CaveBuildLock's harness identity (harness.id, harness.adapter_version, harness.upstream_version) does not match the harness/adapter/upstream versions supplied at execution time. Locked execution is exact-pinned, so any drift between the lock and the actually-loaded runtime is rejected before spend.

Source

Thrown at packages/agent/src/execution-kernel.ts:76

      selected.reasoning !== expectedReasoning) {
    throw new Error("cave_execution_plan_selection_mismatch");
  }
}

export function prepareLockedHarnessExecution(input: {
  build: CaveBuildLock;
  harness: string;
  adapterVersion: string;
  upstreamVersion: string;
  agentId?: string;
  contextIR: ContextIR;
  plan: CavePlan;
}): LockedHarnessPreparation {
  const build = parseCaveBuildLock(input.build);
  if (build.harness.id !== input.harness ||
      build.harness.adapter_version !== input.adapterVersion ||
      build.harness.upstream_version !== input.upstreamVersion) {
    throw new Error("cave_harness_build_mismatch");
  }
  if (input.agentId !== undefined && build.agent_id !== input.agentId) {
    throw new Error("cave_harness_agent_mismatch");
  }
  if (stableStringify(input.plan) !== stableStringify(build.selected_plan)) {
    throw new Error("cave_harness_plan_mismatch");
  }
  const planSHA256 = sha256(stableStringify(input.plan));
  if (planSHA256 !== build.plan_sha256) {
    throw new Error("cave_harness_plan_digest_mismatch");
  }
  const contextIRSHA256 = sha256(stableStringify(contextIRToWire(input.contextIR)));
  if (contextIRSHA256 !== build.context_ir_sha256) {
    throw new Error("cave_harness_context_ir_mismatch");
  }
  const [provider, ...modelParts] = input.plan.model.split("/");
  const model = modelParts.join("/");
  if (!provider || !model) throw new Error("cave_harness_model_invalid");

View on GitHub (pinned to 27d5a3981a)

Solutions

  1. Rebuild the lock (re-run the build/compile step) so harness/adapter/upstream versions in the lock match the current environment.
  2. Check that the harness identifier passed to the execution call is the same one the lock was built for.
  3. Pin the exact same package versions (agent package, adapter, upstream SDK) that were present at build time before re-running.

Example fix

# before
# lock built with agent 1.2.0 / upstream pinned A, then packages upgraded
caveman build && caveman run --lock cave-build.lock # -> cave_harness_build_mismatch

# after
git restore package.json pnpm-lock.yaml # restore exact build-time versions
caveman build # regenerate lock against current pins
caveman run --lock cave-build.lock
Defensive patterns

Strategy: try-catch

Validate before calling

import { FRAMEWORK_VERSION, ADAPTER_VERSION, UPSTREAM_VERSION } from "@caveman-ai/agent";
// before running a locked build, compare recorded lock identity with the current runtime:
const lock = parseCaveBuildLock(rawLock);
const drift = lock.harness.id !== harnessId ||
  lock.harness.adapter_version !== ADAPTER_VERSION ||
  lock.harness.upstream_version !== UPSTREAM_VERSION;
if (drift) await rebuildLock();

Try / catch

try {
  prepareLockedHarness(input);
} catch (e) {
  if (e instanceof Error && e.message === "cave_harness_build_mismatch") {
    // environment drifted from the lock: rebuild, don't retry as-is
    await rebuildLock(input);
  } else throw e;
}

Prevention

When it happens

Trigger: Executing a locked build whose lock file was produced for a different harness id (e.g. pi vs a Vercel/Eve/Mastra adapter) or different adapter/upstream versions than the ones currently installed/registered.

Common situations: Upgrading @caveman-ai/agent or the upstream SDK after the lock was built; switching harness/adapter between build and run; running a lock produced on another machine/CI with different pinned versions; stale lock file committed to the repo.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15). Data as JSON: /api/errors/40ab9feae62bb15c. Report an issue: GitHub.