{"record":{"id":"b455c880ee18c7e2","repo":"JuliusBrussee/caveman","slug":"cave-harness-agent-mismatch","errorCode":"cave_harness_agent_mismatch","errorMessage":"cave_harness_agent_mismatch","messagePattern":"cave_harness_agent_mismatch","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/agent/src/execution-kernel.ts","lineNumber":79,"sourceCode":"}\n\nexport function prepareLockedHarnessExecution(input: {\n  build: CaveBuildLock;\n  harness: string;\n  adapterVersion: string;\n  upstreamVersion: string;\n  agentId?: string;\n  contextIR: ContextIR;\n  plan: CavePlan;\n}): LockedHarnessPreparation {\n  const build = parseCaveBuildLock(input.build);\n  if (build.harness.id !== input.harness ||\n      build.harness.adapter_version !== input.adapterVersion ||\n      build.harness.upstream_version !== input.upstreamVersion) {\n    throw new Error(\"cave_harness_build_mismatch\");\n  }\n  if (input.agentId !== undefined && build.agent_id !== input.agentId) {\n    throw new Error(\"cave_harness_agent_mismatch\");\n  }\n  if (stableStringify(input.plan) !== stableStringify(build.selected_plan)) {\n    throw new Error(\"cave_harness_plan_mismatch\");\n  }\n  const planSHA256 = sha256(stableStringify(input.plan));\n  if (planSHA256 !== build.plan_sha256) {\n    throw new Error(\"cave_harness_plan_digest_mismatch\");\n  }\n  const contextIRSHA256 = sha256(stableStringify(contextIRToWire(input.contextIR)));\n  if (contextIRSHA256 !== build.context_ir_sha256) {\n    throw new Error(\"cave_harness_context_ir_mismatch\");\n  }\n  const [provider, ...modelParts] = input.plan.model.split(\"/\");\n  const model = modelParts.join(\"/\");\n  if (!provider || !model) throw new Error(\"cave_harness_model_invalid\");\n  return Object.freeze({\n    build,\n    plan: build.selected_plan,","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/agent/src/execution-kernel.ts#L61-L97","documentation":"prepareLockedHarnessExecution checks that the build lock's agent_id matches the agent being executed, but only when an agentId is supplied. It throws when executing a locked build against a different agent than the one the build was prepared for. This binds a locked build to a specific agent definition.","triggerScenarios":"Calling prepared or streamAgentInternal with input.agentId set to an agent id different from build.agent_id, typically after switching agent definitions while reusing a cached build lock.","commonSituations":"Renaming or recreating an agent so its id changed while an old lock persisted; running multiple agents but passing the wrong lock; a lock generated in CI for agent A reused locally for agent B.","solutions":["Rebuild the build lock for the agent being executed.","Pass the correct build lock corresponding to input.agentId.","Omit agentId only if the lock intentionally is not agent-bound (and that is acceptable in your flow).","Ensure agent ids are stable and not regenerated per run if locks are cached."],"exampleFix":"// before\nawait streamAgentInternal({ build: lockForAgentA, agentId: \"agent-b\", ... });\n// after\nconst lock = await buildCaveBuildLock({ agentId: \"agent-b\" });\nawait streamAgentInternal({ build: lock, agentId: \"agent-b\", ... });","handlingStrategy":"validation","validationCode":"if (agentId !== undefined && lock.agent_id !== agentId) {\n  lock = await buildCaveBuildLock({ agentId });\n}","typeGuard":"function lockIsForAgent(lock: { agent_id?: string }, agentId: string | undefined): boolean {\n  return agentId === undefined || lock.agent_id === agentId;\n}","tryCatchPattern":"try {\n  await streamAgentInternal({ build: lock, agentId, ... });\n} catch (err) {\n  if (err instanceof Error && err.message === \"cave_harness_agent_mismatch\") {\n    const fresh = await buildCaveBuildLock({ agentId });\n    return streamAgentInternal({ build: fresh, agentId, ... });\n  }\n  throw err;\n}","preventionTips":["Key build locks by agent id and look them up per agent, never share one lock across agents.","Keep agent ids stable across runs when caching locks.","Purge cached locks when agent definitions are renamed or recreated.","Log lock.agent_id and requested agentId together on failure for fast diagnosis."],"tags":["execution-kernel","identity-mismatch","build-lock","agent"],"backgroundTag":"internal-invariant-violation","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}