JuliusBrussee/caveman · error

cannot read pending agent-native bundle journal

Error message

cannot read pending ${agent} agent-native bundle journal: ${(error as Error).message}

What it means

Same family as the bundle journal read error but for the *pending* bundle journal — the staged record of an agent-native bundle install not yet committed. Any read/parse/validation failure other than ENOENT is wrapped and thrown; a missing file is treated as 'no pending journal' (null).

Solutions

  1. Remove the corrupt pending journal file; the CLI then treats it as no pending state.
  2. Fix permissions on the journal file/directory.
  3. Validate the JSON matches schema_version 1 with cloud_mcp and skills fields.
  4. Re-run the install command to rebuild pending state cleanly.
Defensive patterns

Strategy: try-catch

Validate before calling

try { JSON.parse(readFileSync(pendingJournalPath(agent), 'utf8')); } catch { console.warn('pending journal corrupt — safe to delete'); }

Type guard

function isPendingJournal(v: unknown): v is AgentNativeBundleJournal {
  return typeof v === 'object' && v !== null && (v as any).schema_version === 1 &&
    !!((v as any).cloud_mcp) && Array.isArray((v as any).skills);
}

Try / catch

try { runUninstall() } catch (e) { if (String(e.message).includes('cannot read pending')) { fs.rmSync(pendingJournalPath, { force: true }); retry(); } }

Prevention

When it happens

Trigger: readPendingAgentNativeBundleJournal(agent) hits EACCES/EISDIR on the pending journal path, invalid JSON, or schema mismatch (schema_version !== 1, wrong agent, missing cloud_mcp/skills).

Common situations: Interrupted install left a partially written pending journal; permissions changed; schema drift between CLI versions.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20). Data as JSON: /api/errors/059eacf7ca8b4334. Report an issue: GitHub.

Appendix: source

Thrown at packages/cli/src/index.ts:2594

      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}`);
  }
}

type McpServerMarker = { command: string; args: string[]; config_path?: string; schema_version?: 1 };

View on GitHub (pinned to 3ee70a1026)