JuliusBrussee/caveman · error
Aider config has duplicate openai-api-base keys; refusing un
Error message
Aider config has duplicate openai-api-base keys; refusing unsafe merge
What it means
aiderNativeConfig() must replace or wrap the single `openai-api-base:` key in ~/.aider.conf.yml to point Aider at the Caveman route. YAML top-level keys should be unique; if more than one openai-api-base line exists, replacing one would leave ambiguous routing, so it refuses the merge.
Source
Thrown at packages/cli/src/index.ts:6386
];
}
function aiderCorePath(): string {
return join(cavemanHome(), "packs", "aider", "CAVEMAN.md");
}
function aiderCoreSource(): string {
return `${AIDER_NATIVE_CORE_MARKER}\n${NATIVE_CORE}\n\nHost limits: Aider repository map remains authoritative. Caveman observes provider traffic through local proxy; no pre-tool governance or lifecycle interception is active.\n`;
}
function aiderNativeConfig(source: string, route: string, corePath: string): { text: string; routeBlock: string; previousRouteLine: string | null; readBlock: string } {
if ([AIDER_NATIVE_ROUTE_BEGIN, AIDER_NATIVE_ROUTE_END, AIDER_NATIVE_READ_BEGIN, AIDER_NATIVE_READ_END].some((marker) => source.includes(marker))) {
throw new Error("existing Aider Caveman block is unjournaled; run `caveman doctor aider`");
}
const newline = source.includes("\r\n") ? "\r\n" : "\n";
const lines = source.replace(/\r\n/g, "\n").split("\n");
const routeIndexes = lines.flatMap((line, index) => /^openai-api-base\s*:/.test(line) ? [index] : []);
if (routeIndexes.length > 1) throw new Error("Aider config has duplicate openai-api-base keys; refusing unsafe merge");
const routeBlockLines = [AIDER_NATIVE_ROUTE_BEGIN, `openai-api-base: ${yamlQuote(route)}`, AIDER_NATIVE_ROUTE_END];
const routeBlock = routeBlockLines.join(newline);
const previousRouteLine = routeIndexes.length === 1 ? lines[routeIndexes[0]!]! : null;
if (routeIndexes.length === 1) lines.splice(routeIndexes[0]!, 1, ...routeBlockLines);
else {
if (lines.some((line) => line.trim() !== "") && lines[lines.length - 1]?.trim()) lines.push("");
lines.push(...routeBlockLines);
}
const readIndexes = lines.flatMap((line, index) => /^read\s*:/.test(line) ? [index] : []);
if (readIndexes.length > 1) throw new Error("Aider config has duplicate read keys; refusing unsafe merge");
let readBlockLines: string[];
if (readIndexes.length === 1) {
const readIndex = readIndexes[0]!;
if (!/^read\s*:\s*(?:#.*)?$/.test(lines[readIndex]!)) {
throw new Error("Aider config uses inline/scalar read; use block-list form before enabling Caveman");
}
let end = readIndex + 1;View on GitHub (pinned to 27d5a3981a)
Solutions
- Open ~/.aider.conf.yml, find all openai-api-base lines (`grep -n 'openai-api-base' ~/.aider.conf.yml`), keep one, delete the rest
- Retry the caveman install for aider
Example fix
# before — ~/.aider.conf.yml openai-api-base: https://api.openai.com/v1 openai-api-base: https://old-proxy.example/v1 # after openai-api-base: https://api.openai.com/v1
Defensive patterns
Strategy: validation
Validate before calling
import { readFileSync } from "node:fs";
function aiderNoDuplicateRoute(path: string): boolean {
try { return readFileSync(path, "utf8").split(/\r?\n/).filter((l) => /^openai-api-base\s*:/.test(l)).length <= 1; }
catch { return true; }
} Try / catch
try { nativeInstallAider(); } catch (e) {
if (e instanceof Error && /duplicate openai-api-base/.test(e.message)) {
dedupeAiderKey("openai-api-base"); nativeInstallAider();
} else throw e;
} Prevention
- Replace, don't append, when changing openai-api-base in .aider.conf.yml
- Lint YAML configs for duplicate top-level keys (yamllint) before running installers
- Resolve dotfile merge conflicts fully instead of keeping both sides
When it happens
Trigger: Native Aider install when ~/.aider.conf.yml contains two or more lines matching /^openai-api-base\s*:/ (duplicate top-level keys).
Common situations: Append-style edits that added a new base URL without removing the old one; dotfile merges/conflicts; copy-pasting examples onto an existing config.
Related errors
- Aider config has duplicate read keys; refusing unsafe merge
- Aider config uses inline/scalar read; use block-list form be
- Hermes model provider/base_url keys are duplicated; refusing
- existing Aider Caveman block is unjournaled; run `caveman do
- Hermes plugins.enabled uses inline YAML; refusing unsafe nat
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/c665e133bcce9da9.
Report an issue: GitHub.