toon-format/toon · error · ToonDecodeError
Over-indented line: expected depth ${expectedDepth}, but fou
Error message
Over-indented line: expected depth ${expectedDepth}, but found ${line.depth} What it means
At the document root, TOON expects every line at depth 0. In strict mode, a line indented deeper than the root level throws overIndentedLineError, reporting the expected depth (0) and the actual depth found. This catches structurally malformed documents early.
Source
Thrown at packages/toon/src/decode/decoders.ts:97
throw new ToonDecodeError(
'Top-level document must start with a key-value or array-header line',
{ line: first.lineNumber, source: first.raw },
)
}
const rootSeenKeys = options.strict ? new Set<string>() : undefined
yield { type: 'startObject' }
yield* decodeKeyValue(first, reader, 0, options, rootSeenKeys)
while (true) {
const line = yield* peekLine(reader)
if (!line) {
break
}
if (line.depth !== 0) {
if (options.strict) {
throw overIndentedLineError(line, 0)
}
assertNotScalarLine(line)
yield* readLine(reader)
continue
}
yield* readLine(reader)
yield* decodeKeyValue(line, reader, 0, options, rootSeenKeys)
}
yield { type: 'endObject' }
}
// #endregion
// #region Error helpers
function assertNoDepthJump(firstNestedLine: ParsedLine, parentDepth: Depth, strict: boolean): void {View on GitHub (pinned to 604eac266e)
Solutions
- Remove the leading indentation from the lines being decoded
- Decode only the intended sub-document, not an indented fragment
- Set options.strict = false to tolerate over-indented lines (they are skipped per the non-strict path)
- Re-encode the source data to produce properly rooted TOON output
Example fix
// before (input, strict mode) const text = " items: 2" const doc = decode(text) // after const text = "items: 2" const doc = decode(text)
Defensive patterns
Strategy: validation
Validate before calling
function isRootedToon(text: string): boolean {
return text.split('\n').every(line => line.trim() === '' || line[0] !== ' ' && line[0] !== '\t' || /* allow continuation */ true)
} Try / catch
try {
const doc = decode(text)
} catch (e) {
if (e instanceof Error && e.message.includes('Over-indented line')) {
// dedent the input and retry once
const dedented = text.split('\n').map(l => l.replace(/^\s+/, '')).join('\n')
return decode(dedented)
}
throw e
} Prevention
- Strip common leading indentation when extracting TOON snippets from larger files
- Keep strict mode on in CI to catch malformed documents early
- Store TOON as generated by the encoder, never hand-indented
When it happens
Trigger: Calling decode/decodeStreamSync on input whose first meaningful lines (or any non-empty line before any top-level key) are indented, e.g. a document that starts with a line at depth 2, with strict: true (the default).
Common situations: Wrapping TOON output inside YAML/JSON artifacts and decoding the indented block; copy-pasting snippets that carry leading indentation from editors/chat; mixing strict and non-strict workflows.
Related errors
- Indentation depth jump: expected depth ${parentDepth + 1}, b
- Unexpected indentation inside keyed tabular object
- Top-level document must start with a key-value or array-head
- Unexpected bare token line outside root primitive position
- Unexpected content after the document root
AI-assisted analysis of toon-format/toon@604eac266e (2026-08-31).
Data as JSON: /api/errors/0236dbde3499ce29.
Report an issue: GitHub.