JuliusBrussee/caveman · error · Error
cannot read pending ${agent} agent-native bundle journal: ${
Error message
cannot read pending ${agent} agent-native bundle journal: ${(error as Error).message} What it means
readPendingAgentNativeBundleJournal() reads the '.pending' variant of the agent-native bundle journal — the transaction record of an in-flight skill/MCP installation. A non-ENOENT error (bad JSON, or shape validation failing: schema_version !== 1, wrong agent, missing cloud_mcp, non-array skills) is rethrown with this message before any recovery is attempted.
Source
Thrown at packages/cli/src/index.ts:2309
throw new Error("unsupported bundle journal");
}
return value;
} catch (error) {
if ((error as NodeJS.ErrnoException).code === "ENOENT") return null;
throw new Error(`cannot read ${agent} agent-native bundle journal: ${(error as Error).message}`);
}
}
function readPendingAgentNativeBundleJournal(agent: "claude" | "codex"): AgentNativeBundleJournal | null {
try {
const value = JSON.parse(readFileSync(agentNativeBundleJournalPath(agent, true), "utf8")) as AgentNativeBundleJournal;
if (value.schema_version !== 1 || value.agent !== agent || !value.cloud_mcp || !Array.isArray(value.skills)) {
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 {View on GitHub (pinned to 27d5a3981a)
Solutions
- Inspect the pending journal file and compare it to the committed journal for the agent
- If the interrupted setup's target state is irrelevant, delete the pending journal and re-run setup to redo the bundle cleanly
- Ensure only one caveman process runs setup per agent (the integration lock) to avoid partial writes
Defensive patterns
Strategy: try-catch
Validate before calling
function pendingJournalIntact(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 isPendingJournalReadError(e: unknown): boolean {
return e instanceof Error && e.message.includes("cannot read pending ") && e.message.includes("bundle journal");
} Try / catch
try {
runCavemanAgentCommand("codex");
} catch (e) {
if (isPendingJournalReadError(e)) {
// an interrupted setup left a partial .pending journal — resolve it before any agent command
} else throw e;
} Prevention
- Let `caveman setup` run to completion; avoid killing it mid-bundle-install
- After a crash, re-run the same setup command first so recovery completes before other work
- Keep one caveman process per agent (integration lock exists for a reason)
When it happens
Trigger: A previous `caveman setup` / agent-native install was killed mid-transaction leaving a partially written .pending journal, then any later agent command runs recovery and hits the malformed file; or a CLI version skew changed the journal schema between write and read.
Common situations: Ctrl-C or SIGKILL during `caveman claude` setup; power loss; two caveman processes racing (no integration lock held); manual editing of the pending journal.
Related errors
- cannot read ${agent} agent-native bundle journal: ${(error a
- cannot read pending ${agent} agent-native removal journal: $
- could not install 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/059eacf7ca8b4334.
Report an issue: GitHub.