{"record":{"id":"7c61fac4659ee5be","repo":"toon-format/toon","slug":"expected-list-item","errorCode":null,"errorMessage":"Expected list item","messagePattern":"Expected list item","errorType":"exception","errorClass":"ReferenceError","httpStatus":null,"severity":"error","filePath":"packages/toon/src/decode/decoders.ts","lineNumber":534,"sourceCode":"\n  if (options.strict && startLine !== undefined && endLine !== undefined) {\n    validateNoBlankLinesInRange(startLine, endLine, reader.scanState.blankLines, options.strict, 'list-form array')\n  }\n\n  if (options.strict) {\n    const nextLine = yield* peekLine(reader)\n    validateNoExtraListItems(nextLine, itemDepth, header.length)\n  }\n}\n\nfunction* decodeListItem(\n  reader: LineReader,\n  baseDepth: Depth,\n  options: DecoderContext,\n): LineRule {\n  const line = yield* readLine(reader)\n  if (!line) {\n    throw new ReferenceError('Expected list item')\n  }\n\n  let afterHyphen: string\n\n  if (line.content === LIST_ITEM_MARKER) {\n    yield { type: 'startObject' }\n    yield { type: 'endObject' }\n    return\n  }\n  else if (line.content.startsWith(LIST_ITEM_PREFIX)) {\n    afterHyphen = line.content.slice(LIST_ITEM_PREFIX.length)\n  }\n  else {\n    throw new ToonDecodeError(\n      `Expected list item to start with \"${LIST_ITEM_PREFIX}\"`,\n      { line: line.lineNumber, source: line.raw },\n    )\n  }","sourceCodeStart":516,"sourceCodeEnd":552,"githubUrl":"https://github.com/toon-format/toon/blob/604eac266e35166bed6f5b9e3bd586e9c60a9330/packages/toon/src/decode/decoders.ts#L516-L552","documentation":"decodeListItem is asked to consume one list item but the line reader returned no line (end of input), so the structure promises a `- ` item that is missing. This is thrown as a plain ReferenceError, indicating truncated input rather than a styled ToonDecodeError.","triggerScenarios":"decodeListArray iterating N declared items calls decodeListItem, but the stream ends before the expected `- ` line — e.g. the declared array length exceeds the number of list-item lines present.","commonSituations":"A truncated or manually edited file where the `[3]:` header still claims 3 items but only 2 remain; a generator bug writing fewer items than declared; line-loss from a bad merge.","solutions":["Add the missing `- ` list item line","Correct the count in the array header (e.g. `[3]:` -> `[2]:`)","Regenerate the document from the source data","Verify the file was not truncated in transit"],"exampleFix":"// before\ntags[2]:\n  - a\n\n// after\ntags[2]:\n  - a\n  - b","handlingStrategy":"try-catch","validationCode":"function listItemsMatchCount(text: string): boolean {\n  const m = text.match(/^ *\\[(\\d+)\\]:/m)\n  if (!m) return true\n  const want = Number(m[1])\n  const got = text.split('\\n').filter(l => /^ *- /.test(l)).length\n  return got >= want\n}","typeGuard":"function hasEnoughListItems(text: string): boolean {\n  const header = text.match(/\\[(\\d+)\\]/)\n  if (!header) return true\n  const count = (text.match(/^\\s*- /gm) ?? []).length\n  return count >= Number(header[1])\n}","tryCatchPattern":"try {\n  return decode(input)\n} catch (e) {\n  if (e instanceof ReferenceError && e.message === 'Expected list item') {\n    throw new Error('Input truncated: declared list length exceeds available items')\n  }\n  throw e\n}","preventionTips":["Keep the array-header count in sync with the item lines","Regenerate documents from data instead of hand-editing lengths","Check files for truncation after transfer/merge"],"tags":["toon","decoder","list","truncated-input"],"backgroundTag":"array-length-mismatch","analyzedSha":"604eac266e35166bed6f5b9e3bd586e9c60a9330","analyzedAt":"2026-08-31T11:09:25.043Z","schemaVersion":2},"datasetVersion":"2026-09-01T08:17:40.651Z"}