JuliusBrussee/caveman · error
${label}:${lineNo}: nested line without an open block
Error message
${label}:${lineNo}: nested line without an open block What it means
Thrown by the catalog parser when a line at indent 4 (the nested block level) appears while blockKey is null — i.e. no indent-2 key was left "open" as a valueless block header. Indent-4 content is only meaningful as the contents of a block key like " models:"; without one, the parser cannot tell which property the nested line belongs to.
Source
Thrown at scripts/generate-agent-catalog.mjs:87
}
if (row === null) throw new Error(`${label}:${lineNo}: indented line before any row`);
if (indent === 2) {
if (dash) throw new Error(`${label}:${lineNo}: unexpected sequence item at row level`);
const entry = splitKeyValue(rest, label, lineNo);
if (Object.prototype.hasOwnProperty.call(row, entry.key)) {
throw new Error(`${label}:${lineNo}: duplicate key "${entry.key}"`);
}
if (entry.value === undefined) {
blockKey = entry.key;
row[entry.key] = undefined;
} else {
blockKey = null;
row[entry.key] = entry.value;
}
continue;
}
if (indent === 4) {
if (blockKey === null) throw new Error(`${label}:${lineNo}: nested line without an open block`);
if (dash) {
if (row[blockKey] === undefined) row[blockKey] = [];
if (!Array.isArray(row[blockKey])) throw new Error(`${label}:${lineNo}: "${blockKey}" mixes map and sequence entries`);
row[blockKey].push(rest);
continue;
}
if (row[blockKey] === undefined) row[blockKey] = {};
if (Array.isArray(row[blockKey]) || typeof row[blockKey] !== "object") {
throw new Error(`${label}:${lineNo}: "${blockKey}" mixes map and sequence entries`);
}
const entry = splitKeyValue(rest, label, lineNo);
if (entry.value === undefined) throw new Error(`${label}:${lineNo}: nesting deeper than two levels is not supported`);
if (Object.prototype.hasOwnProperty.call(row[blockKey], entry.key)) {
throw new Error(`${label}:${lineNo}: duplicate key "${blockKey}.${entry.key}"`);
}
row[blockKey][entry.key] = entry.value;
continue;
}View on GitHub (pinned to 27d5a3981a)
Solutions
- Insert the block header at indent 2 with no inline value above the nested lines: " models:" then the indent-4 items.
- If the indent-4 line is really a row property, dedent it to 2 spaces.
- Remove inline values from keys that are meant to open blocks — "key: value" closes the block, "key:" opens it.
Example fix
# before
- provider: anthropic
models: all
- claude-4
# after
- provider: anthropic
models:
- claude-4 Defensive patterns
Strategy: validation
Validate before calling
function indent4AlwaysUnderOpenBlock(text) {
let openBlock = false;
for (const line of text.split("\n")) {
if (/^ {2}[A-Za-z_][A-Za-z0-9_]*:\s*$/.test(line.replace(/\s+$/, ""))) openBlock = true;
else if (/^ {2}\S/.test(line)) openBlock = false;
else if (/^ {4}/.test(line) && !openBlock) return false;
}
return true;
} Try / catch
try {
parseCatalog(text);
} catch (err) {
if (/nested line without an open block/.test(err.message)) {
// add the valueless indent-2 key header above the indent-4 lines
} else throw err;
} Prevention
- Remember the rule: "key: value" closes a block, "key:" alone opens one.
- When converting an inline value to a list, delete the inline value in the same edit.
When it happens
Trigger: Writing indent-4 lines directly after an inline-valued property, e.g. " models: default" followed by " - claude-4"; or deleting/commenting the " key:" header line while leaving its children.
Common situations: Editor auto-indent carrying 4 spaces onto a line that should be at 2; converting an inline value to a list but forgetting to strip the inline value; merge conflict cleanup removing the block header.
Related errors
- ${label}:${lineNo}: unexpected sequence item at row level
- ${label}:${lineNo}: unexpected indent of ${indent} spaces
- ${label}:${lineNo}: expected a top-level "- provider: ..." r
- ${label}:${lineNo}: row must start with an inline "provider"
- ${label}:${lineNo}: indented line before any row
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/9186ae22c21dd595.
Report an issue: GitHub.