{"record":{"id":"c5720ccb7abe5ec7","repo":"JuliusBrussee/caveman","slug":"aider-config-uses-inline-scalar-read-use-block-li","errorCode":null,"errorMessage":"Aider config uses inline/scalar read; use block-list form before enabling Caveman","messagePattern":"Aider config uses inline/scalar read; use block-list form before enabling Caveman","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cli/src/index.ts","lineNumber":6402,"sourceCode":"  const lines = source.replace(/\\r\\n/g, \"\\n\").split(\"\\n\");\n  const routeIndexes = lines.flatMap((line, index) => /^openai-api-base\\s*:/.test(line) ? [index] : []);\n  if (routeIndexes.length > 1) throw new Error(\"Aider config has duplicate openai-api-base keys; refusing unsafe merge\");\n  const routeBlockLines = [AIDER_NATIVE_ROUTE_BEGIN, `openai-api-base: ${yamlQuote(route)}`, AIDER_NATIVE_ROUTE_END];\n  const routeBlock = routeBlockLines.join(newline);\n  const previousRouteLine = routeIndexes.length === 1 ? lines[routeIndexes[0]!]! : null;\n  if (routeIndexes.length === 1) lines.splice(routeIndexes[0]!, 1, ...routeBlockLines);\n  else {\n    if (lines.some((line) => line.trim() !== \"\") && lines[lines.length - 1]?.trim()) lines.push(\"\");\n    lines.push(...routeBlockLines);\n  }\n\n  const readIndexes = lines.flatMap((line, index) => /^read\\s*:/.test(line) ? [index] : []);\n  if (readIndexes.length > 1) throw new Error(\"Aider config has duplicate read keys; refusing unsafe merge\");\n  let readBlockLines: string[];\n  if (readIndexes.length === 1) {\n    const readIndex = readIndexes[0]!;\n    if (!/^read\\s*:\\s*(?:#.*)?$/.test(lines[readIndex]!)) {\n      throw new Error(\"Aider config uses inline/scalar read; use block-list form before enabling Caveman\");\n    }\n    let end = readIndex + 1;\n    while (end < lines.length && !/^[A-Za-z0-9][A-Za-z0-9_-]*\\s*:/.test(lines[end]!)) end++;\n    readBlockLines = [`  ${AIDER_NATIVE_READ_BEGIN}`, `  - ${yamlQuote(corePath)}`, `  ${AIDER_NATIVE_READ_END}`];\n    lines.splice(end, 0, ...readBlockLines);\n  } else {\n    if (lines.some((line) => line.trim() !== \"\") && lines[lines.length - 1]?.trim()) lines.push(\"\");\n    readBlockLines = [AIDER_NATIVE_READ_BEGIN, \"read:\", `  - ${yamlQuote(corePath)}`, AIDER_NATIVE_READ_END];\n    lines.push(...readBlockLines);\n  }\n  const readBlock = readBlockLines.join(newline);\n  const text = lines.join(newline).replace(/(?:\\r?\\n)+$/, \"\") + newline;\n  return { text, routeBlock, previousRouteLine, readBlock };\n}\n\nfunction aiderNativeMutations(gw: string): NativeMutation[] {\n  const configPath = join(homedir(), \".aider.conf.yml\");\n  const configBefore = fileBytes(configPath);","sourceCodeStart":6384,"sourceCodeEnd":6420,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/packages/cli/src/index.ts#L6384-L6420","documentation":"aiderNativeConfig() only knows how to append items to a block-list `read:` key (i.e. `read:` on its own line with `- item` lines below). If the existing key carries an inline value (`read: file.md` or `read: [a, b]`), line-based block insertion would corrupt the YAML, so it throws and asks the user to normalize first.","triggerScenarios":"Native Aider install when ~/.aider.conf.yml contains `read: ./some.md` or `read: [a.md, b.md]` — anything not matching /^read\\s*:\\s*(#.*)?$/.","commonSituations":"Aider configs commonly use the inline single-file form; users pasting compact examples; tools generating flow-style YAML.","solutions":["Edit ~/.aider.conf.yml and expand the read key to block-list form","Re-run the caveman aider install, which will then insert its marked entry safely"],"exampleFix":"# before\nread: ./CONVENTIONS.md\n\n# after\nread:\n  - ./CONVENTIONS.md","handlingStrategy":"validation","validationCode":"import { readFileSync } from \"node:fs\";\nfunction aiderReadIsBlockForm(path: string): boolean {\n  try {\n    const line = readFileSync(path, \"utf8\").split(/\\r?\\n/).find((l) => /^read\\s*:/.test(l));\n    return line === undefined || /^read\\s*:\\s*(#.*)?$/.test(line);\n  } catch { return true; }\n}","typeGuard":null,"tryCatchPattern":"try { nativeInstallAider(); } catch (e) {\n  if (e instanceof Error && /inline\\/scalar read/.test(e.message)) {\n    expandReadToBlockList(); nativeInstallAider();\n  } else throw e;\n}","preventionTips":["Prefer block-list YAML style for list keys in configs managed by line-based tools","Avoid flow-style (inline arrays) and single-file scalar forms for read:","Normalize config style before running integration installers"],"tags":["aider","yaml","inline-scalar","merge-safety"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}