JuliusBrussee/caveman · error
${skill.file} changed after setup; refusing destructive bund
Error message
${skill.file} changed after setup; refusing destructive bundle removal What it means
Safety gate in removeAgentNativeBundle (--remove): before destructively uninstalling, each journaled skill file must still hash to after_sha256. If a skill file is missing or was modified since setup, removal aborts rather than overwrite/lose user changes layered on top of the installed skills.
Source
Thrown at packages/cli/src/index.ts:2610
throw new Error(`${agent} caveman-cloud MCP registration failed exact postflight`);
}
for (const skill of journal.skills) {
const current = fileBytes(skill.file);
if (!current || bytesHash(current) !== skill.after_sha256) throw new Error(`${skill.file} failed skill postflight`);
}
}
function removeAgentNativeBundle(agent: "claude" | "codex"): void {
recoverPendingAgentNativeRemoval(agent);
recoverPendingAgentNativeBundle(agent);
const journal = readAgentNativeBundleJournal(agent);
if (!journal) {
process.stderr.write(`${mark("warn")} ${agent}: no agent-native bundle journal found\n`);
return;
}
for (const skill of journal.skills) {
const current = fileBytes(skill.file);
if (!current || bytesHash(current) !== skill.after_sha256) throw new Error(`${skill.file} changed after setup; refusing destructive bundle removal`);
}
const marker = readMcpServerMarker(agent, "caveman-cloud");
if (!sameMcpCommand(marker, journal.cloud_mcp) || !agentNativeCloudMcpMatches(agent, journal.cloud_mcp)) {
throw new Error(`${agent} caveman-cloud MCP changed after setup; refusing destructive bundle removal`);
}
if (journal.native_owned) {
const nativeJournal = readNativeJournal(agent);
if (nativeJournal) {
for (const operation of nativeJournal.operations) restoreNativeOperation(operation);
}
}
atomicWriteFile(agentNativeBundleRemovalJournalPath(agent), Buffer.from(JSON.stringify(journal, null, 2) + "\n"));
try {
restoreAgentNativeBundleSkills(journal.skills);
restoreAgentNativeCloudMcp(agent, journal.previous_cloud_mcp);
if (journal.native_owned) disableNativeAgent(agent);
unlinkSync(agentNativeBundleJournalPath(agent));
unlinkSync(agentNativeBundleRemovalJournalPath(agent));View on GitHub (pinned to 27d5a3981a)
Solutions
- If you intentionally modified the skills, back them up, restore them to the installed content (or delete them knowingly), then re-run --remove
- Reinstall the bundle (`caveman setup --agent-native <agent>`) to reset skill files to journaled hashes, then immediately run --remove
- Locate the offending path from the error message and diff it against the installed version before deciding to discard changes
Defensive patterns
Strategy: validation
Validate before calling
// before --remove: verify journaled skills are unmodified
import { createHash } from "node:crypto";
import { readFileSync } from "node:fs";
for (const skill of journal.skills) {
let bytes: Buffer;
try { bytes = readFileSync(skill.file); } catch { throw new Error(`${skill.file} missing; removal will abort`); }
if (createHash("sha256").update(bytes).digest("hex") !== skill.after_sha256) {
throw new Error(`${skill.file} modified; back it up or reinstall before --remove`);
}
} Try / catch
try {
await setup(["--agent-native", agent, "--remove"]);
} catch (error) {
if (/refusing destructive bundle removal/.test((error as Error).message) && /failed skill postflight|changed after setup/.test((error as Error).message)) {
// back up the named file, reinstall bundle to reset hashes, then remove
await backupAndReset(skillFileFromMessage(error));
await setup(["--agent-native", agent, "--remove"]);
} else throw error;
} Prevention
- Treat installed skill files as read-only; keep customizations in separate files
- Reinstall the bundle right before removing it to guarantee hash alignment
- Back up the agent skills directory before destructive operations
When it happens
Trigger: Running `caveman setup --agent-native <agent> --remove` after a skill file in the journal was edited, deleted, or rewritten by the agent or the user.
Common situations: User customized an installed SKILL.md; the agent updated its own skill files; sync conflicts changed file contents since the bundle was installed.
Related errors
- ${agent} caveman-cloud MCP changed after setup; refusing des
- ${skill.file} changed during interrupted setup; refusing des
- ${skill.file} changed during interrupted removal; refusing d
- ${file} already exists with non-canonical content; refusing
- ${file} changed after setup; refusing to overwrite user skil
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/e55ae937fbc3f3c0.
Report an issue: GitHub.