JuliusBrussee/caveman · error

${label}:${lineNo}: "${blockKey}" mixes map and sequence ent

Error message

${label}:${lineNo}: "${blockKey}" mixes map and sequence entries

What it means

Thrown by the catalog parser (dash branch) when a "- " item at indent 4 is added to a block key whose value was already established as a map (an object), not a sequence. The parser allows a block key to hold either a list of items or a map of sub-keys, but not both — mixing them would produce an ambiguous structure the generator cannot render.

Source

Thrown at scripts/generate-agent-catalog.mjs:90

      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;
    }
    throw new Error(`${label}:${lineNo}: unexpected indent of ${indent} spaces`);
  }
  return rows;

View on GitHub (pinned to 27d5a3981a)

Solutions

  1. Pick one shape for the block named in the error: all indent-4 "- item" lines (sequence) or all indent-4 "key: value" lines (map), and rewrite the block accordingly.
  2. If you need both, split into two sibling block keys at indent 2 (e.g. "endpoints:" and "default_endpoint:").

Example fix

# before
- provider: anthropic
  endpoints:
    default: /v1/messages
    - /v1/count_tokens

# after
- provider: anthropic
  endpoints:
    - /v1/messages
    - /v1/count_tokens
  default_endpoint: /v1/messages
Defensive patterns

Strategy: validation

Validate before calling

function blockNotMixed(text) {
  const blocks = new Map();
  let current = null;
  for (const line of text.split("\n")) {
    const m = /^ {2}([A-Za-z_][A-Za-z0-9_]*):\s*$/.exec(line.replace(/\s+$/, ""));
    if (m) { current = m[1]; blocks.set(current, new Set()); continue; }
    if (/^ {4}- /.test(line) && current) blocks.get(current).add("seq");
    else if (/^ {4}[A-Za-z_]/.test(line) && current) blocks.get(current).add("map");
  }
  return [...blocks.values()].every((s) => s.size <= 1);
}

Try / catch

try {
  parseCatalog(text);
} catch (err) {
  if (/mixes map and sequence entries/.test(err.message)) {
    // split the named blockKey into one sequence block and one map block
  } else throw err;
}

Prevention

When it happens

Trigger: Under one block key, first writing " subkey: value" (making it a map) and later " - item" (a sequence item), e.g. " endpoints:" containing both " - /v1" and " default: /v1".

Common situations: Growing a config block incrementally where an early map entry sets the type and a later edit adds list items (or vice versa); pasting heterogeneous examples into one block.

Related errors


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