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

  1. Flatten to two levels: combine the keys, e.g. " limits:" + " context: 200000" instead of a third level.
  2. 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

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


AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15). Data as JSON: /api/errors/4103bdd51fb2bd3d. Report an issue: GitHub.