{"record":{"id":"5372b45c344af842","repo":"JuliusBrussee/caveman","slug":"agent-caveman-cloud-mcp-registration-failed-exa","errorCode":null,"errorMessage":"${agent} caveman-cloud MCP registration failed exact postflight","messagePattern":"(.+?) caveman-cloud MCP registration failed exact postflight","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cli/src/index.ts","lineNumber":2592,"sourceCode":"    mkdirSync(dirname(file), { recursive: true });\n    atomicWriteFile(file, Buffer.from(body));\n    return {\n      file,\n      before_base64: originals.get(file) ?? null,\n      after_sha256: bytesHash(Buffer.from(body)),\n    };\n  });\n}\n\nfunction verifyAgentNativeBundle(agent: \"claude\" | \"codex\", journal: AgentNativeBundleJournal, cloudMcp: { command: string; args: string[] }): void {\n  const status = nativeIntegrationStatus(agent);\n  if (status.state !== \"installed\") throw new Error(`${agent} native integration postflight is ${status.state}`);\n  const marker = readMcpServerMarker(agent, \"caveman-cloud\");\n  if (!marker || marker.command !== cloudMcp.command || JSON.stringify(marker.args) !== JSON.stringify(cloudMcp.args)) {\n    throw new Error(`${agent} caveman-cloud MCP postflight mismatch`);\n  }\n  if (!agentNativeCloudMcpMatches(agent, cloudMcp)) {\n    throw new Error(`${agent} caveman-cloud MCP registration failed exact postflight`);\n  }\n  for (const skill of journal.skills) {\n    const current = fileBytes(skill.file);\n    if (!current || bytesHash(current) !== skill.after_sha256) throw new Error(`${skill.file} failed skill postflight`);\n  }\n}\n\nfunction removeAgentNativeBundle(agent: \"claude\" | \"codex\"): void {\n  recoverPendingAgentNativeRemoval(agent);\n  recoverPendingAgentNativeBundle(agent);\n  const journal = readAgentNativeBundleJournal(agent);\n  if (!journal) {\n    process.stderr.write(`${mark(\"warn\")} ${agent}: no agent-native bundle journal found\\n`);\n    return;\n  }\n  for (const skill of journal.skills) {\n    const current = fileBytes(skill.file);\n    if (!current || bytesHash(current) !== skill.after_sha256) throw new Error(`${skill.file} changed after setup; refusing destructive bundle removal`);","sourceCodeStart":2574,"sourceCodeEnd":2610,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/packages/cli/src/index.ts#L2574-L2610","documentation":"Final and strictest MCP postflight in verifyAgentNativeBundle: even if the marker matches textually, agentNativeCloudMcpMatches(agent, cloudMcp) must confirm the agent's live registration of the caveman-cloud server is exactly the applied one. It catches semantic mismatches the marker comparison misses (e.g. normalized paths, env expansion, duplicate entries).","triggerScenarios":"The config file contains the marker but the agent-side registration resolves differently: binary path resolved via symlink/PATH to another caveman build, duplicate caveman-cloud entries where the agent picks the stale one, or env-var interpolation inside args that changes after write.","commonSituations":"Multiple caveman installs on PATH (npm global vs setup --install binary) so the registered command points at an older binary; leftover duplicate MCP entries from earlier setups; agent config normalizing absolute paths on save.","solutions":["Ensure exactly one caveman binary is on PATH and reinstall the agent-native bundle so registration points at it","Delete duplicate \"caveman-cloud\" entries in the agent's mcpServers config, then re-run setup","Run `which caveman` and compare against the command recorded in the agent config; align them (e.g. via CAVEMAN_AGENT_BIN or reinstall)","Re-run `caveman setup --agent-native <agent>` after `--remove` to force a clean registration"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// pre-flight: single caveman binary on PATH prevents registration pointing at stale builds\nimport { execSync } from \"node:child_process\";\nconst hits = execSync(\"which -a caveman\", { encoding: \"utf8\" }).trim().split(\"\\n\");\nif (hits.length > 1) console.warn(`multiple caveman binaries: ${hits.join(\", \")}; unify before agent-native setup`);","typeGuard":null,"tryCatchPattern":"try {\n  await setup([\"--agent-native\", agent]);\n} catch (error) {\n  if (/failed exact postflight/.test((error as Error).message)) {\n    // exact-match failure means live registration differs; remove + clean reinstall\n    await setup([\"--agent-native\", agent, \"--remove\"]);\n    await setup([\"--agent-native\", agent]);\n  } else throw error;\n}","preventionTips":["Keep exactly one caveman install on PATH (prefer `caveman setup --install` over ad-hoc npm globals)","Remove duplicate caveman-cloud entries in agent config before setup","Pin CAVEMAN_AGENT_BIN/overrides to one absolute binary path in automation"],"tags":["postflight","mcp","agent-native","path-resolution"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}