{"record":{"id":"4363a4d9fe141d9d","repo":"toon-format/toon","slug":"top-level-document-must-start-with-a-key-value-or","errorCode":null,"errorMessage":"Top-level document must start with a key-value or array-header line","messagePattern":"Top-level document must start with a key-value or array-header line","errorType":"exception","errorClass":"ToonDecodeError","httpStatus":null,"severity":"error","filePath":"packages/toon/src/decode/decoders.ts","lineNumber":79,"sourceCode":"    const headerInfo = withLine(first, () => resolveArrayHeader(parseArrayHeaderLine(first.content, DEFAULT_DELIMITER), options.strict))\n    if (headerInfo) {\n      yield* readLine(reader)\n      yield* decodeArrayFromHeader(headerInfo.header, headerInfo.inlineValues, reader, 0, options, first)\n      yield* assertFullyConsumed(reader, options.strict)\n      return\n    }\n  }\n\n  yield* readLine(reader)\n  const following = yield* peekLine(reader)\n  const hasMore = following !== undefined\n  if (!hasMore && !isKeyValueLine(first)) {\n    yield { type: 'primitive', value: withLine(first, () => parsePrimitiveToken(first.content)) }\n    return\n  }\n\n  if (!isKeyValueLine(first) && following?.depth === 0) {\n    throw new ToonDecodeError(\n      'Top-level document must start with a key-value or array-header line',\n      { line: first.lineNumber, source: first.raw },\n    )\n  }\n\n  const rootSeenKeys = options.strict ? new Set<string>() : undefined\n  yield { type: 'startObject' }\n  yield* decodeKeyValue(first, reader, 0, options, rootSeenKeys)\n\n  while (true) {\n    const line = yield* peekLine(reader)\n    if (!line) {\n      break\n    }\n\n    if (line.depth !== 0) {\n      if (options.strict) {\n        throw overIndentedLineError(line, 0)","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/toon-format/toon/blob/604eac266e35166bed6f5b9e3bd586e9c60a9330/packages/toon/src/decode/decoders.ts#L61-L97","documentation":"TOON documents must begin with either a single primitive value or a top-level `key: value` / `[N]:` array-header line. decodeDocument throws this when the first line is neither a parseable primitive nor a key-value line while the stream is not a one-line primitive document, so no valid root can be established. It is a structural error in the input text, not a runtime state problem.","triggerScenarios":"Calling decodeStreamSync/decodeStream (or decode) on input whose first line is a bare token that contains no unquoted colon and is not a `- ` list item, and where a following line exists at depth 0 (so it cannot be treated as a lone root primitive).","commonSituations":"Hand-written TOON files that start with a stray value or comment-like text; truncated files where the opening key was lost; pasting only a nested fragment (e.g. the body of an object) instead of the whole document; tooling that emits YAML with the root key stripped.","solutions":["Start the document with a `key: value` line or an `[N]{...}:` array header at depth 0","If the input is a single bare value, ensure it is the only line so the primitive-root path is taken","Check for missing/renamed root key or accidental leading blank/garbage lines","Wrap the fragment in a root key before decoding"],"exampleFix":"// before\n\"just a bare value\"\nanother line\n\n// after\nroot: \"just a bare value\"\nnested:\n  another: line","handlingStrategy":"validation","validationCode":"function looksLikeToonDocument(text: string): boolean {\n  const first = text.split('\\n', 1)[0]?.trim() ?? ''\n  if (!first) return false\n  if (first.startsWith('- ')) return false\n  return /^[^:\\s][^:]*:/.test(first) || /^\\[\\d+\\]/.test(first)\n}\nif (!looksLikeToonDocument(input)) throw new Error('Input is not a rooted TOON document')","typeGuard":"function isRootedToon(text: string): boolean {\n  const first = text.split('\\n', 1)[0] ?? ''\n  return /:\\s*/.test(first) || /^\\[\\d+\\]/.test(first)\n}","tryCatchPattern":"try {\n  const doc = decode(input, { strict: true })\n} catch (e) {\n  if (e instanceof ToonDecodeError && /Top-level document/.test(e.message)) {\n    // recover: wrap fragment or surface a user-facing parse error\n  } else throw e\n}","preventionTips":["Always emit documents through the TOON encoder rather than string concatenation","Validate the first line starts with `key:` or `[N]:` before decoding","Never paste bare object fragments without wrapping in a root key"],"tags":["toon","decoder","strict-mode","malformed-input"],"backgroundTag":"malformed-document-root","analyzedSha":"604eac266e35166bed6f5b9e3bd586e9c60a9330","analyzedAt":"2026-08-31T11:09:25.043Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}