{"record":{"id":"978a46ae0480a16b","repo":"JuliusBrussee/caveman","slug":"mcp-servers-caveman-cloud-exists-but-is-not-cave","errorCode":null,"errorMessage":"[mcp_servers.caveman-cloud] exists but is not Caveman-journaled; refusing overwrite","messagePattern":"\\[mcp_servers\\.caveman-cloud\\] exists but is not Caveman-journaled; refusing overwrite","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cli/src/index.ts","lineNumber":2567,"sourceCode":"    if (current && !current.equals(Buffer.from(body)) && (!previous || bytesHash(current) !== previous.after_sha256)) {\n      throw new Error(`${file} changed after setup; refusing to overwrite user skill edits`);\n    }\n  }\n  if (agent === \"claude\") {\n    const actual = claudeMcpRegistration(\"caveman-cloud\");\n    const marker = readMcpServerMarker(\"claude\", \"caveman-cloud\");\n    if (actual.present && !marker) {\n      throw new Error(\"Claude caveman-cloud MCP exists but is not Caveman-journaled; refusing overwrite\");\n    }\n    if (actual.present && marker && !agentNativeCloudMcpMatches(\"claude\", marker)) {\n      throw new Error(\"Claude caveman-cloud MCP changed after setup; refusing to overwrite user fields\");\n    }\n    return;\n  }\n  const config = fileBytes(join(homedir(), \".codex\", \"config.toml\"))?.toString(\"utf8\") ?? \"\";\n  if (!config.includes(\"[mcp_servers.caveman-cloud]\")) return;\n  if (!readMcpServerMarker(\"codex\", \"caveman-cloud\")) {\n    throw new Error(\"[mcp_servers.caveman-cloud] exists but is not Caveman-journaled; refusing overwrite\");\n  }\n}\n\nfunction installAgentNativeBundleSkills(agent: \"claude\" | \"codex\", journal: AgentNativeBundleJournal): void {\n  const originals = new Map(journal.skills.map((skill) => [skill.file, skill.before_base64]));\n  journal.skills = agentNativeSkillFiles(agent).map(({ file, body }) => {\n    mkdirSync(dirname(file), { recursive: true });\n    atomicWriteFile(file, Buffer.from(body));\n    return {\n      file,\n      before_base64: originals.get(file) ?? null,\n      after_sha256: bytesHash(Buffer.from(body)),\n    };\n  });\n}\n\nfunction verifyAgentNativeBundle(agent: \"claude\" | \"codex\", journal: AgentNativeBundleJournal, cloudMcp: { command: string; args: string[] }): void {\n  const status = nativeIntegrationStatus(agent);","sourceCodeStart":2549,"sourceCodeEnd":2585,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/packages/cli/src/index.ts#L2549-L2585","documentation":"Codex-specific preflight: ~/.codex/config.toml contains a [mcp_servers.caveman-cloud] table, but no Caveman marker file exists for it. As with the Claude case, an unjournaled registration has unknown provenance and Caveman refuses to overwrite it during agent-native setup.","triggerScenarios":"Manually adding [mcp_servers.caveman-cloud] to ~/.codex/config.toml; using a pre-marker Caveman version; CODEX_HOME pointing at a config that already had the table; deleting ~/.caveman-cloud/integrations markers.","commonSituations":"Hand-edited codex config; config restored/synced without the caveman home; leftover from an older caveman release.","solutions":["Remove the [mcp_servers.caveman-cloud] table from ~/.codex/config.toml and re-run setup so Caveman installs and journals it","Or rename your custom table to a different server key if you want to keep it","Check CODEX_HOME is set as intended so setup reads/writes the config you actually use"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"function codexCavemanCloudJournaled(): boolean {\n  const toml = readFileSync(join(homedir(), \".codex\", \"config.toml\"), \"utf8\");\n  if (!toml.includes(\"[mcp_servers.caveman-cloud]\")) return true;\n  return existsSync(join(cavemanHome(), \"mcp\", \"codex.caveman-cloud.json\"));\n}","typeGuard":"function isUnjournaledCodexMcpError(e: unknown): boolean {\n  return e instanceof Error && e.message === \"[mcp_servers.caveman-cloud] exists but is not Caveman-journaled; refusing overwrite\";\n}","tryCatchPattern":"try {\n  runCavemanSetup();\n} catch (e) {\n  if (isUnjournaledCodexMcpError(e)) {\n    // delete the [mcp_servers.caveman-cloud] table (or rename its key), then re-run\n  } else throw e;\n}","preventionTips":["Let caveman manage the caveman-cloud table in ~/.codex/config.toml","Set CODEX_HOME deliberately and keep markers in sync with the config you use"],"tags":["mcp","codex","preflight","safety"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}