JuliusBrussee/caveman · error · Error
cannot read pending ${agent} agent-native removal journal: $
Error message
cannot read pending ${agent} agent-native removal journal: ${(error as Error).message} What it means
readPendingAgentNativeBundleRemoval() reads the '.removing' journal that records an in-flight uninstall of the agent-native bundle. Like its siblings, only ENOENT is tolerated; corrupt JSON or a shape that fails validation (schema_version, agent match, cloud_mcp presence, skills array) is rethrown with this message, blocking removal recovery.
Source
Thrown at packages/cli/src/index.ts:2322
throw new Error("unsupported pending bundle journal");
}
return value;
} catch (error) {
if ((error as NodeJS.ErrnoException).code === "ENOENT") return null;
throw new Error(`cannot read pending ${agent} agent-native bundle journal: ${(error as Error).message}`);
}
}
function readPendingAgentNativeBundleRemoval(agent: "claude" | "codex"): AgentNativeBundleJournal | null {
try {
const value = JSON.parse(readFileSync(agentNativeBundleRemovalJournalPath(agent), "utf8")) as AgentNativeBundleJournal;
if (value.schema_version !== 1 || value.agent !== agent || !value.cloud_mcp || !Array.isArray(value.skills)) {
throw new Error("unsupported pending bundle removal journal");
}
return value;
} catch (error) {
if ((error as NodeJS.ErrnoException).code === "ENOENT") return null;
throw new Error(`cannot read pending ${agent} agent-native removal journal: ${(error as Error).message}`);
}
}
function readMcpServerMarker(agent: string, serverName: string): { command: string; args: string[] } | null {
try {
const value = JSON.parse(readFileSync(mcpServerMarkerPath(agent, serverName), "utf8")) as Record<string, unknown>;
if (typeof value.command !== "string" || !Array.isArray(value.args) || !value.args.every((arg) => typeof arg === "string")) return null;
return { command: value.command, args: value.args as string[] };
} catch {
return null;
}
}
function claudeMcpRegistration(serverName: string): { present: boolean; command: string; args: string[]; exact_shape: boolean } {
const path = join(homedir(), ".claude.json");
const bytes = fileBytes(path);
if (!bytes) return { present: false, command: "", args: [], exact_shape: false };
const root = parseJsonFileObject(path, bytes);View on GitHub (pinned to 27d5a3981a)
Solutions
- Inspect ~/.caveman-cloud/integrations/<agent>.agent-native-bundle.removing.json
- If the removal was nearly complete, finish it manually (delete the skills dirs and MCP entry the journal lists) and remove the journal, or restore from the committed journal
- Delete the malformed removal journal and re-run the uninstall command to rebuild a clean transaction
Defensive patterns
Strategy: try-catch
Validate before calling
function removalJournalIntact(p: string): boolean {
try {
const v = JSON.parse(readFileSync(p, "utf8"));
return v.schema_version === 1 && Array.isArray(v.skills) && !!v.cloud_mcp;
} catch { return false; }
} Type guard
function isRemovalJournalReadError(e: unknown): boolean {
return e instanceof Error && e.message.includes("cannot read pending ") && e.message.includes("removal journal");
} Try / catch
try {
runCavemanAgentCommand("claude");
} catch (e) {
if (isRemovalJournalReadError(e)) {
// finish or discard the interrupted removal: fix/remove the .removing.json, then re-run
} else throw e;
} Prevention
- Do not kill uninstall mid-way; if you must, re-run it promptly to let recovery settle
- Treat ~/.caveman-cloud/integrations/*.removing.json as transaction files — never edit or partially copy them
- Keep backups of the agent config when experimenting with interrupted installs
When it happens
Trigger: An interrupted `caveman setup` removal/uninstall step (killed between journaling and commit) leaves a malformed .agent-native-bundle.removing.json; a subsequent agent command triggers recoverPendingAgentNativeRemoval which fails to parse it.
Common situations: Uninstall killed by timeout in CI; crash during removal; journal schema changed across CLI versions; disk corruption.
Related errors
- cannot read pending ${agent} agent-native bundle journal: ${
- cannot read ${agent} agent-native bundle journal: ${(error a
- could not remove caveman-cloud MCP for ${agent}
- ${skill.file} changed during interrupted setup; refusing des
- ${agent} caveman-cloud MCP changed during interrupted setup;
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/7bcb3af77c8b9899.
Report an issue: GitHub.