JuliusBrussee/caveman · error
${label}:${lineNo}: nesting deeper than two levels is not su
Error message
${label}:${lineNo}: nesting deeper than two levels is not supported What it means
Thrown by the catalog parser when an indent-4 line inside a map block is itself a valueless key (" key:" with no inline value). The parser supports exactly two nesting levels; a key that opens a third level has no representation in the generated catalog, so it is rejected rather than silently dropped.
Source
Thrown at scripts/generate-agent-catalog.mjs:99
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;
}
throw new Error(`${label}:${lineNo}: unexpected indent of ${indent} spaces`);
}
return rows;
}
function splitKeyValue(text, label, lineNo) {
const match = /^([A-Za-z_][A-Za-z0-9_]*):(?: (.*))?$/.exec(text);
if (match === null) throw new Error(`${label}:${lineNo}: cannot read "${text}" as a "key: value" pair`);
return { key: match[1], value: match[2] === undefined ? undefined : scalar(match[2], label, lineNo) };
}
function scalar(text, label, lineNo) {View on GitHub (pinned to 27d5a3981a)
Solutions
- Flatten to two levels: combine the keys, e.g. " limits:" + " context: 200000" instead of a third level.
- If the value is genuinely a nested document, move it to a separate file the generator supports — this parser will not carry it.
Example fix
# before
- provider: anthropic
limits:
context:
tokens: 200000
# after
- provider: anthropic
limits:
context_tokens: 200000 Defensive patterns
Strategy: validation
Validate before calling
function maxTwoLevels(text) {
return text.split("\n").every((line) => !/^ {4}[A-Za-z_][A-Za-z0-9_]*:\s*$/.test(line.replace(/\s+$/, "")));
} Try / catch
try {
parseCatalog(text);
} catch (err) {
if (/nesting deeper than two levels/.test(err.message)) {
// flatten the valueless indent-4 key into a combined "parent_child: value" pair
} else throw err;
} Prevention
- Keep catalog data flat by design — two levels maximum.
- Move deeply structured config to a real YAML/JSON file consumed by other tooling.
When it happens
Trigger: Writing a block key at indent 2 whose children are also block headers, e.g. " limits:" then " context:" intended to be followed by indent-6 values — the indent-4 "context:" line with no value triggers the error immediately.
Common situations: Porting a deeply nested YAML config (k8s-style) into the catalog format; organically growing config depth over time; pasting a nested fragment without flattening it.
Related errors
- ${label}:${lineNo}: expected a top-level "- provider: ..." r
- ${label}:${lineNo}: row must start with an inline "provider"
- ${label}:${lineNo}: indented line before any row
- ${label}:${lineNo}: unexpected sequence item at row level
- ${label}:${lineNo}: duplicate key "${entry.key}"
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/4103bdd51fb2bd3d.
Report an issue: GitHub.