{"record":{"id":"7bcb3af77c8b9899","repo":"JuliusBrussee/caveman","slug":"cannot-read-pending-agent-agent-native-removal","errorCode":null,"errorMessage":"cannot read pending ${agent} agent-native removal journal: ${(error as Error).message}","messagePattern":"cannot read pending (.+?) agent-native removal journal: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cli/src/index.ts","lineNumber":2607,"sourceCode":"      throw new Error(\"unsupported pending bundle journal\");\n    }\n    return value;\n  } catch (error) {\n    if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return null;\n    throw new Error(`cannot read pending ${agent} agent-native bundle journal: ${(error as Error).message}`);\n  }\n}\n\nfunction readPendingAgentNativeBundleRemoval(agent: \"claude\" | \"codex\"): AgentNativeBundleJournal | null {\n  try {\n    const value = JSON.parse(readFileSync(agentNativeBundleRemovalJournalPath(agent), \"utf8\")) as AgentNativeBundleJournal;\n    if (value.schema_version !== 1 || value.agent !== agent || !value.cloud_mcp || !Array.isArray(value.skills)) {\n      throw new Error(\"unsupported pending bundle removal journal\");\n    }\n    return value;\n  } catch (error) {\n    if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return null;\n    throw new Error(`cannot read pending ${agent} agent-native removal journal: ${(error as Error).message}`);\n  }\n}\n\ntype McpServerMarker = { command: string; args: string[]; config_path?: string; schema_version?: 1 };\n\nfunction mcpServerToolName(serverName: string): string | undefined {\n  if (serverName === \"caveman\") return \"caveman_retrieve\";\n  if (serverName === \"caveman-browse\") return \"caveman_browse\";\n  if (serverName === \"caveman-cloud\") return \"caveman_context\";\n  if (serverName === \"caveman-delegate\") return \"caveman_delegate\";\n  return undefined;\n}\n\nfunction parseMcpServerMarkerBytes(agent: string, serverName: string, bytes: Buffer): McpServerMarker | null {\n  try {\n    const value = JSON.parse(bytes.toString(\"utf8\")) as Record<string, unknown>;\n    const expectedTool = mcpServerToolName(serverName);\n    if (!expectedTool || value.tool !== expectedTool) return null;","sourceCodeStart":2589,"sourceCodeEnd":2625,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/cli/src/index.ts#L2589-L2625","documentation":"Same pattern for the pending bundle *removal* journal — the staged record of a bundle uninstall not yet applied. Non-ENOENT failures (permission, invalid JSON, schema mismatch) are wrapped in this error; a missing file yields null.","triggerScenarios":"readPendingAgentNativeBundleRemoval(agent) fails on the removal journal path with EACCES/EISDIR, malformed JSON, or schema validation failure (schema_version !== 1, wrong agent, missing cloud_mcp/skills).","commonSituations":"Interrupted uninstall left a partial removal journal; manual edits broke the JSON; version mismatch on schema.","solutions":["Delete the corrupt pending removal journal to clear the stuck state.","Repair file permissions on the journal path.","Check the JSON conforms to schema_version 1 with the expected fields.","Re-run the uninstall command after cleanup."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"try { JSON.parse(readFileSync(removalJournalPath(agent), 'utf8')); } catch { console.warn('removal journal corrupt — safe to delete'); }","typeGuard":"function isRemovalJournal(v: unknown): v is AgentNativeBundleJournal {\n  return typeof v === 'object' && v !== null && (v as any).schema_version === 1 &&\n    ['claude','codex'].includes((v as any).agent);\n}","tryCatchPattern":"try { uninstall() } catch (e) { if (String(e.message).includes('cannot read pending') && String(e.message).includes('removal')) { fs.rmSync(removalJournalPath, { force: true }); uninstall(); } }","preventionTips":["Complete or cleanly abort uninstalls instead of force-killing the process.","Validate JSON before manually restoring config from backups.","Pin one CLI version per machine to avoid schema drift."],"tags":["json","journal","uninstall","file-read"],"backgroundTag":"json-parse-error","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}