toon-format/toon · error · ToonDecodeError

Expected ${expectedCount} list-form items, but found more

Error message

Expected ${expectedCount} list-form items, but found more

What it means

Thrown by validateNoExtraListItems when a list-form array declared with [N] items contains MORE list items than declared: after reading N items, the next line is still a list-item bullet ('- ') at the same depth. This is a strict/structural integrity check that prevents silently truncating extra data. Unlike error 35 it is not gated on strict mode in this function — an extra item at item depth always throws.

Source

Thrown at packages/toon/src/decode/validation.ts:29

  itemType: string,
  options: { strict: boolean },
  line: ParsedLine,
): void {
  if (options.strict && actual !== expected) {
    throw new ToonDecodeError(
      `Expected ${expected} ${itemType}, but got ${actual}`,
      { line: line.lineNumber, source: line.raw },
    )
  }
}

export function validateNoExtraListItems(
  nextLine: ParsedLine | undefined,
  itemDepth: Depth,
  expectedCount: number,
): void {
  if (nextLine?.depth === itemDepth && nextLine.content.startsWith(LIST_ITEM_PREFIX)) {
    throw new ToonDecodeError(
      `Expected ${expectedCount} list-form items, but found more`,
      { line: nextLine.lineNumber, source: nextLine.raw },
    )
  }
}

export function validateNoExtraTabularRows(
  nextLine: ParsedLine | undefined,
  rowDepth: Depth,
  header: ArrayHeaderInfo,
): void {
  if (
    nextLine?.depth === rowDepth
    && !nextLine.content.startsWith(LIST_ITEM_PREFIX)
    && isDataRow(nextLine.content, header.delimiter)
  ) {
    throw new ToonDecodeError(
      `Expected ${header.length} tabular rows, but found more`,

View on GitHub (pinned to 604eac266e)

Solutions

  1. Delete the extra bullet lines beyond the N declared items
  2. Update the header count from [N] to the actual number of '- ' items
  3. If extra items are plausible input, validate/normalize the payload before decode

Example fix

// before
items[2]:
  - a
  - b
  - c
// after
items[3]:
  - a
  - b
  - c
Defensive patterns

Strategy: validation

Validate before calling

const bullets = lines.filter(l => /^\s*- /.test(l)).length
if (bullets !== declaredCount) throw new Error(`list has ${bullets} items, header declares ${declaredCount}`)

Type guard

function listItemsMatchCount(body: string[], n: number): boolean { return body.filter(l => l.trimStart().startsWith('- ')).length === n }

Try / catch

try { decode(input) } catch (e) { if (e instanceof ToonDecodeError && e.message.includes('list-form items, but found more')) console.error('extra list item near line', e.line?.lineNumber, e.line?.source) }

Prevention

When it happens

Trigger: Decoding a list-form array (decodeListArray) whose body contains more '- ' bullet lines at the array's item depth than the header count [N] declares.

Common situations: Hand-edited or merged TOON files where bullets were appended without updating the count; a client serializing N+1 items but a stale header; copy/paste duplication of a bullet line.

Related errors


AI-assisted analysis of toon-format/toon@604eac266e (2026-08-31). Data as JSON: /api/errors/3b58e0ddfaa709df. Report an issue: GitHub.