JuliusBrussee/caveman · error
existing Codex Caveman block is corrupted; run `caveman…
Error message
existing Codex Caveman block is corrupted; run `caveman doctor codex`
What it means
The Codex installer strips previously-installed Caveman TOML blocks (root, tables, provider, MCP) by matching begin/end markers before re-emitting them. If exactly one of a begin/end marker pair is present, or the end marker appears before the begin marker, the block is considered corrupted and the installer refuses to proceed, directing the user to `caveman doctor codex`.
Solutions
- Run `caveman doctor codex` to detect and repair the corrupted block, then re-run enable.
- Manually remove all remaining Caveman marker lines and enclosed content from the TOML so the config is clean, then re-run install.
- Restore config.toml from a backup taken before the Caveman install and re-run the enable flow.
Example fix
// before (config.toml) # caveman:native-root-begin model_provider = "caveman" // (end marker missing) // after `caveman doctor codex` model_provider = "openai" // clean config; re-run enable to re-add complete block
Defensive patterns
Strategy: validation
Validate before calling
const toml = readFileSync(codexCfg, 'utf8');
for (const [b, e] of [[ROOT_BEGIN, ROOT_END], [TABLES_BEGIN, TABLES_END]]) {
const s = toml.indexOf(b), f = toml.indexOf(e);
if ((s === -1) !== (f === -1) || f < s) {
// run `caveman doctor codex` before enabling
}
} Try / catch
try {
await cavemanEnableCodex();
} catch (e) {
if (String(e.message).includes('corrupted')) {
await cavemanDoctorCodex();
await cavemanEnableCodex();
}
} Prevention
- Never hand-delete only part of a marker-delimited Caveman TOML block.
- Keep BEGIN/END marker comment lines intact when editing config.toml.
- Run `caveman doctor codex` after any manual edit to ~/.codex/config.toml.
- Back up config.toml before enabling or upgrading.
When it happens
Trigger: Running the Codex enable/install flow when ~/.codex/config.toml contains a half-intact Caveman block: a begin marker without its end marker, an end marker without its begin, or end preceding begin.
Common situations: Manual edits to config.toml that deleted only part of a Caveman block; interrupted installs or rollbacks; comment-stripping/minifying tools removing marker comment lines; copy/paste edits that moved lines out of order.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- exists and is not exact Caveman-owned content; refusing to…
- could not install caveman-cloud MCP for
- existing Aider Caveman block is unjournaled; run `caveman…
- existing Hermes Caveman native block is unjournaled; run…
- : MCP ownership journal failed; native config may already…
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/812fc8f4ca9b2390.
Report an issue: GitHub.
Appendix: source
Thrown at packages/cli/src/index.ts:7488
kind: "aider-core",
owned: { marker: AIDER_NATIVE_CORE_MARKER },
},
];
}
function codexNativeConfig(source: string, gw: string, subscription: boolean, mcpBinary: string): { text: string; rootBlock: string; tablesBlock: string } {
// Remove caveman's own marker blocks FIRST. The legacy table strippers below
// skip every line after a caveman table until the next TOML header, and the
// tables block ends with [mcp_servers.caveman] followed by the end marker, so
// running them first ate "# <<< caveman:native-tables" and the block this
// function had itself written failed its own re-parse as "corrupted" on the
// next wrap (every `caveman codex` run fell back to session-only wrap and
// doctor reported drift).
let stripped = source;
for (const [begin, end] of [[CODEX_NATIVE_ROOT_BEGIN, CODEX_NATIVE_ROOT_END], [CODEX_NATIVE_TABLES_BEGIN, CODEX_NATIVE_TABLES_END]] as const) {
const start = stripped.indexOf(begin);
const finish = stripped.indexOf(end);
if ((start === -1) !== (finish === -1) || finish < start) throw new Error("existing Codex Caveman block is corrupted; run `caveman doctor codex`");
if (start !== -1) stripped = `${stripped.slice(0, start)}${stripped.slice(finish + end.length)}`.trim();
}
stripped = stripCodexCavemanMcpToml(stripCodexCavemanProviderToml(stripped));
const rootBlock = `${CODEX_NATIVE_ROOT_BEGIN}\nmodel_provider = "caveman"\n${CODEX_NATIVE_ROOT_END}`;
const providerLines = codexCavemanProviderToml(gw, subscription).split("\n").slice(1).join("\n");
const tablesBlock = [
CODEX_NATIVE_TABLES_BEGIN,
providerLines,
"",
"[mcp_servers.caveman]",
`command = ${JSON.stringify(mcpBinary)}`,
CODEX_RECOVERY_ENV,
CODEX_NATIVE_TABLES_END,
].join("\n");
const middle = stripped ? `\n\n${stripped}` : "";
return { text: `${rootBlock}${middle}\n\n${tablesBlock}\n`, rootBlock, tablesBlock };
}
View on GitHub (pinned to 3ee70a1026)