JuliusBrussee/caveman · error
${label}:${lineNo}: indented line before any row
Error message
${label}:${lineNo}: indented line before any row What it means
Thrown by the catalog parser when an indented line appears before any top-level "- provider: ..." row has been opened. Indented content can only belong to a row; with row still null there is nothing to attach it to, which almost always means the file's first row is malformed or missing its dash.
Source
Thrown at scripts/generate-agent-catalog.mjs:70
for (let index = 0; index < lines.length; index++) {
const line = lines[index].replace(/\s+$/, "");
const lineNo = index + 1;
if (line === "" || /^ *#/.test(line)) continue;
const shape = /^( *)(- )?(.*)$/.exec(line);
const indent = shape[1].length;
const dash = shape[2] !== undefined;
const rest = shape[3];
if (indent === 0) {
if (!dash) throw new Error(`${label}:${lineNo}: expected a top-level "- provider: ..." row`);
row = {};
rows.push(row);
blockKey = null;
const entry = splitKeyValue(rest, label, lineNo);
if (entry.value === undefined) throw new Error(`${label}:${lineNo}: row must start with an inline "provider" value`);
row[entry.key] = entry.value;
continue;
}
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) {View on GitHub (pinned to 27d5a3981a)
Solutions
- Go to the line named by label:lineNo and add the missing top-level "- provider: <value>" row above it.
- If the orphaned lines belong to a row that was deleted, remove them too or restore the row.
- Run the generator again to confirm no further structure errors follow.
Example fix
# before model: claude-4 api: messages # after - provider: anthropic model: claude-4 api: messages
Defensive patterns
Strategy: validation
Validate before calling
function firstContentLineIsRow(text) {
const first = text.split("\n").find((l) => l.trim() !== "" && !/^ *#/.test(l));
return first !== undefined && /^- provider: /.test(first.trimEnd());
} Try / catch
try {
parseCatalog(text);
} catch (err) {
if (/indented line before any row/.test(err.message)) {
// restore the "- provider: ..." header above the line named in the error
} else throw err;
} Prevention
- Run the generator immediately after structural edits to catch orphaned lines.
- Avoid editors that auto-reindent the whole file on save.
When it happens
Trigger: The file starts with indented keys (e.g. the "- provider:" line was deleted or commented out, or the whole file was re-indented by an editor), or a comment marker was removed leaving orphaned child lines at the top.
Common situations: Accidentally deleting the first row's dash line while editing; a formatter re-indenting the file; resolving a merge conflict by keeping only the indented half.
Related errors
- ${label}:${lineNo}: expected a top-level "- provider: ..." r
- ${label}:${lineNo}: row must start with an inline "provider"
- ${label}:${lineNo}: unexpected sequence item at row level
- ${label}:${lineNo}: duplicate key "${entry.key}"
- ${label}:${lineNo}: nested line without an open block
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/c5ef506ad35d08bb.
Report an issue: GitHub.