JuliusBrussee/caveman · error · Error
${agent} caveman-cloud MCP changed during interrupted setup;
Error message
${agent} caveman-cloud MCP changed during interrupted setup; refusing destructive recovery What it means
The MCP-side guard of interrupted-setup recovery: the on-disk caveman-cloud registration must match the pending target, the recorded previous MCP, or the committed journal's MCP; the marker file (if present) must equally match one of those. If neither holds, the user (or another tool) changed the MCP registration during the interrupted window, and overwriting it would destroy their changes — so recovery refuses.
Source
Thrown at packages/cli/src/index.ts:2443
const currentMatchesBefore = current === null ? before === null : before !== null && bytesHash(current) === bytesHash(before);
const currentHash = current ? bytesHash(current) : null;
const currentMatchesCommitted = currentHash !== null && currentHash === committedSkills.get(skill.file);
if (!currentMatchesBefore && !currentMatchesCommitted && currentHash !== skill.after_sha256) {
throw new Error(`${skill.file} changed during interrupted setup; refusing destructive recovery`);
}
}
const marker = readMcpServerMarker(agent, "caveman-cloud");
const markerKnown = !marker
|| sameMcpCommand(marker, pending.cloud_mcp)
|| sameMcpCommand(marker, pending.previous_cloud_mcp)
|| sameMcpCommand(marker, committed?.cloud_mcp ?? null);
const hostInstalled = agentNativeCloudMcpMatches(agent, pending.cloud_mcp);
const hostPrevious = pending.previous_cloud_mcp
? agentNativeCloudMcpMatches(agent, pending.previous_cloud_mcp)
: agentNativeCloudMcpHostAbsent(agent);
const hostCommitted = committed ? agentNativeCloudMcpMatches(agent, committed.cloud_mcp) : false;
if (!markerKnown || (!hostInstalled && !hostPrevious && !hostCommitted)) {
throw new Error(`${agent} caveman-cloud MCP changed during interrupted setup; refusing destructive recovery`);
}
restoreInstalledAgentNativeBundle(agent, pending);
unlinkSync(agentNativeBundleJournalPath(agent, true));
process.stderr.write(`${mark("warn")} completed interrupted ${agent} agent-native bundle before continuing\n`);
}
function skillMatchesBefore(skill: AgentNativeBundleSkill): boolean {
const current = fileBytes(skill.file);
const before = skill.before_base64 === null ? null : Buffer.from(skill.before_base64, "base64");
return current === null ? before === null : before !== null && current.equals(before);
}
function agentNativeCloudMcpHostAbsent(agent: "claude" | "codex"): boolean {
if (agent === "claude") return !claudeMcpRegistration("caveman-cloud").present;
const config = fileBytes(join(homedir(), ".codex", "config.toml"))?.toString("utf8") ?? "";
return !config.includes("[mcp_servers.caveman-cloud]");
}
View on GitHub (pinned to 27d5a3981a)
Solutions
- Decide which registration you want: either revert your manual caveman-cloud edits so recovery can complete, or keep them and clear the pending journal to abandon the transaction
- Re-run setup after resolving — it will either complete or re-journal from the new state
- Avoid editing the caveman-cloud MCP entry by hand; use caveman's own install/uninstall commands so markers stay consistent
Defensive patterns
Strategy: validation
Validate before calling
function mcpInKnownState(current: { command: string; args: string[] } | null, options: Array<{ command: string; args: string[] } | null>): boolean {
return options.some((o) => o && current && current.command === o.command && JSON.stringify(current.args) === JSON.stringify(o.args));
} Type guard
function isMcpChangedDuringSetupError(e: unknown): boolean {
return e instanceof Error && e.message.includes("caveman-cloud MCP changed during interrupted setup");
} Try / catch
try {
runCavemanAgentCommand("claude");
} catch (e) {
if (isMcpChangedDuringSetupError(e)) {
// revert manual caveman-cloud edits or clear the pending journal, then re-run
} else throw e;
} Prevention
- Never edit the caveman-cloud MCP entry by hand; use caveman install/uninstall commands
- Resolve interrupted setups before reconfiguring MCP servers
- Keep ~/.caveman-cloud/integrations markers intact
When it happens
Trigger: Interrupt a setup, then manually edit the caveman-cloud entry in ~/.claude.json (different command/args) or remove it and install a different caveman-cloud server, then run an agent command that triggers recovery.
Common situations: User pointed caveman-cloud at a custom gateway/binary; another caveman version rewrote the registration; the marker file under ~/.caveman-cloud/integrations was deleted or edited while the host config changed.
Related errors
- ${skill.file} changed during interrupted setup; refusing des
- ${agent} caveman-cloud MCP changed during interrupted remova
- cannot read pending ${agent} agent-native bundle journal: ${
- cannot read pending ${agent} agent-native removal journal: $
- could not install caveman-cloud MCP for ${agent}
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/fcb6810b62d1891e.
Report an issue: GitHub.