JuliusBrussee/caveman · error
agent-native bundle removal failed: ${(error as Error).messa
Error message
agent-native bundle removal failed: ${(error as Error).message}; installed bundle restored What it means
removeAgentNativeBundle failed partway (error in the try block), but the compensating restoreInstalledAgentNativeBundle succeeded: the installed bundle was put back and the removal journal cleaned up. State is back to installed; only the removal attempt itself failed.
Source
Thrown at packages/cli/src/index.ts:2636
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));
} catch (error) {
try {
restoreInstalledAgentNativeBundle(agent, journal);
unlinkSync(agentNativeBundleRemovalJournalPath(agent));
} catch (rollback) {
throw new Error(`agent-native bundle removal failed: ${(error as Error).message}; rollback incomplete: ${(rollback as Error).message}`);
}
throw new Error(`agent-native bundle removal failed: ${(error as Error).message}; installed bundle restored`);
}
process.stderr.write(`${mark("ok")} ${agent}: agent-native bundle removed; prior skills and cloud MCP restored\n`);
}
async function setup(argv: string[] = []) {
const json = argv.includes("--json");
const install = argv.includes("--install");
const removeBundle = argv.includes("--remove");
const agentNative = flagFrom(argv, "--agent-native", "");
const hasAgentNativeFlag = argv.includes("--agent-native") || argv.some((arg) => arg.startsWith("--agent-native="));
const unknown = argv.filter((arg, index) =>
arg !== "--json"
&& arg !== "--install"
&& arg !== "--remove"
&& arg !== "--agent-native"
&& !arg.startsWith("--agent-native=")
&& argv[index - 1] !== "--agent-native");
if (unknown.length > 0 || (hasAgentNativeFlag && !agentNative) || (agentNative && (json || install)) || (removeBundle && !agentNative)) {View on GitHub (pinned to 27d5a3981a)
Solutions
- Read the embedded original error message — it names the failing step; address it (close agent, fix permissions)
- Re-run `caveman setup --agent-native <agent> --remove` once the blocking condition is gone
- If it persists, run setup again to normalize the bundle, then remove
Defensive patterns
Strategy: retry
Validate before calling
import { accessSync, constants } from "node:fs";
accessSync(join(homedir(), agentConfigName(agent)), constants.W_OK); // throws early if unwritable Try / catch
try {
await setup(["--agent-native", agent, "--remove"]);
} catch (error) {
const msg = (error as Error).message;
if (/installed bundle restored/.test(msg)) {
// state is safely back to installed; the embedded original error is the actionable part
await resolveOriginalFailure(extractOriginal(msg)); // e.g. close agent
await setup(["--agent-native", agent, "--remove"]); // safe to retry once
} else throw error;
} Prevention
- Close the agent before removal — transient config locks are the top cause
- Treat 'installed bundle restored' as a clean, retryable failure
- Parse the embedded original error rather than retrying unchanged
When it happens
Trigger: Running --remove when one step (skill restore, MCP restore, native disable, or journal unlink) fails while the rest of the environment is healthy enough to restore the bundle.
Common situations: Transient failure such as a config file momentarily locked by the agent; a single skill path unwritable; then the agent exits and restore succeeds.
Related errors
- ${skill.file} changed after setup; refusing destructive bund
- ${agent} caveman-cloud MCP changed after setup; refusing des
- agent-native bundle removal failed: ${(error as Error).messa
- agent-native setup failed: ${(error as Error).message}${roll
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/bcaaea94f108f5bf.
Report an issue: GitHub.