JuliusBrussee/caveman · error · Error
Aider Caveman config block changed after enable; refusing de
Error message
Aider Caveman config block changed after enable; refusing destructive disable
What it means
Thrown by `caveman disable aider` when ~/.aider.conf.yml drifted after enable (hash differs from after_sha256) and the exact journaled route_block or read_block strings are no longer present verbatim in the file. Caveman only removes what it can match exactly; if its owned blocks were edited or reformatted, removal could cut into your content, so it refuses the destructive disable.
Source
Thrown at packages/cli/src/index.ts:7696
}
if (mcp.caveman !== undefined) {
if (operation.owned?.previous_mcp === null || operation.owned?.previous_mcp === undefined) delete mcp.caveman;
else mcp.caveman = operation.owned.previous_mcp;
}
if (Object.keys(mcp).length > 0) root.mcp = mcp;
else delete root.mcp;
return jsonBytes(root);
}
if (operation.kind === "aider-config") {
let text = current.toString("utf8");
const routeBlock = operation.owned?.route_block;
const readBlock = operation.owned?.read_block;
const previousRouteLine = operation.owned?.previous_route_line;
if (typeof routeBlock !== "string" || typeof readBlock !== "string") {
throw new Error("Aider integration journal lacks owned blocks");
}
if (!text.includes(routeBlock) || !text.includes(readBlock)) {
throw new Error("Aider Caveman config block changed after enable; refusing destructive disable");
}
text = text.replace(routeBlock, typeof previousRouteLine === "string" ? previousRouteLine : "");
text = text.replace(readBlock, "");
return Buffer.from(text.replace(/\n{3,}/g, "\n\n"));
}
if (operation.kind === "aider-core") {
throw new Error(`${operation.file} changed after enable; refusing destructive disable`);
}
if (operation.kind === "hermes-plugin-manifest" || operation.kind === "hermes-plugin-init") {
throw new Error(`${operation.file} changed after enable; refusing destructive disable`);
}
if (operation.kind === "hermes-config") {
let text = current.toString("utf8");
const routeBlock = operation.owned?.route_block;
const previousRouteLines = operation.owned?.previous_route_lines;
if (typeof routeBlock !== "string" || !Array.isArray(previousRouteLines)) {
throw new Error("Hermes integration journal lacks owned routing block");
}View on GitHub (pinned to 2f49f0e1a3)
Solutions
- Restore the owned blocks to the exact strings in owned.route_block / owned.read_block of ~/.caveman/integrations/aider.json, then rerun `caveman disable aider`
- Run `caveman doctor aider` first to see per-file drift, and reconcile only the reported lines
- If the edits must stay: manually strip the Caveman blocks from ~/.aider.conf.yml and delete ~/.caveman/integrations/aider.json
- Re-run `caveman enable aider` to re-journal the current content, then disable immediately
Example fix
# before: the caveman-owned block in ~/.aider.conf.yml was edited # >>> caveman:native-routing openai-api-base: http://localhost:9999/v1 # changed from installed route # after: block matches owned.route_block byte-for-byte, then `caveman disable aider` succeeds
Defensive patterns
Strategy: try-catch
Validate before calling
// Confirm the exact owned blocks still exist in ~/.aider.conf.yml before disable
import { readFileSync } from 'node:fs';
const home = process.env.CAVEMAN_HOME ?? `${process.env.HOME}/.caveman`;
const j = JSON.parse(readFileSync(`${home}/integrations/aider.json`, 'utf8'));
const text = readFileSync(`${process.env.HOME}/.aider.conf.yml`, 'utf8');
for (const op of j.operations) {
if (op.kind === 'aider-config' && (!text.includes(op.owned.route_block) || !text.includes(op.owned.read_block))) {
console.error('refusing: caveman blocks in .aider.conf.yml were edited');
}
} Try / catch
catch (err) { if (err.message.includes('config block changed after enable')) { /* diff .aider.conf.yml against owned blocks in the journal; restore them verbatim; retry once */ } else throw err; } Prevention
- Keep caveman-added lines in .aider.conf.yml untouched; make custom edits outside the caveman blocks
- Run `caveman doctor aider` before scripted disable
- If you edit the routing lines by accident, re-run `caveman enable aider` to re-stamp
When it happens
Trigger: Editing the Caveman routing or read-tool lines in ~/.aider.conf.yml after `caveman enable aider` — e.g. changing the annotated model/settings lines, reordering them, or a formatter normalizing YAML indentation — then running `caveman disable aider`.
Common situations: Tweaking the OpenAI base URL line Caveman added to point elsewhere; aider or an editor rewriting/reformatting the YAML; merging dotfile changes via git that touch the same lines.
Related errors
- ${agent} ${event} Caveman hook changed after enable; refusin
- ${operation.file} was removed after enable; refusing destruc
- Claude ANTHROPIC_BASE_URL changed after enable; refusing des
- Claude caveman MCP entry changed after enable; refusing dest
- Gemini caveman MCP entry changed after enable; refusing dest
AI-assisted analysis of JuliusBrussee/caveman@2f49f0e1a3 (2026-08-18).
Data as JSON: /api/errors/10910b95a8faaa5d.
Report an issue: GitHub.