toon-format/toon · error · Error
Array startArray event without preceding key
Error message
Array startArray event without preceding key
What it means
applyEvent received a startArray event while the parent is an object with no pending currentKey. Arrays inside objects must be assigned under a key, so the builder throws.
Source
Thrown at packages/toon/src/decode/event-builder.ts:104
if (stack.length === 0) {
state.root = context.obj
}
break
}
case 'startArray': {
const arr: JsonValue[] = []
if (stack.length === 0) {
stack.push({ type: 'array', arr })
}
else {
const parent = stack[stack.length - 1]!
if (parent.type === 'object') {
if (parent.currentKey === undefined) {
throw new Error('Array startArray event without preceding key')
}
setOwnProperty(parent.obj, parent.currentKey, arr)
parent.currentKey = undefined
}
else if (parent.type === 'array') {
parent.arr.push(arr)
}
stack.push({ type: 'array', arr })
}
break
}
case 'endArray': {
if (stack.length === 0) {
throw new Error('Unexpected endArray event')
}View on GitHub (pinned to 604eac266e)
Solutions
- Emit a key event before startArray when inside an object
- Fix the upstream tokenizer/emitter ordering
- Validate key-before-value ordering in the stream beforehand
Example fix
// before
[{type:'startObject'},{type:'startArray'},{type:'endArray'}]
// after
[{type:'startObject'},{type:'key',key:'items'},{type:'startArray'},{type:'endArray'}] Defensive patterns
Strategy: validation
Validate before calling
function keysPrecedeArrays(events) {
let inObject = false, expectKey = false
for (const ev of events) {
if (ev.type === 'startObject') { inObject = true; expectKey = false }
else if (ev.type === 'endObject') inObject = false
else if (ev.type === 'key') expectKey = true
else if (ev.type === 'startArray' && inObject && !expectKey) return false
else if (ev.type === 'endArray') expectKey = false
}
return true
} Try / catch
try {
const value = buildValueFromEvents(events)
} catch (e) {
if (e.message.includes('Array startArray event without preceding key')) {
throw new Error('Nested array emitted without a key in object context')
}
throw e
} Prevention
- Emit a key event before startArray whenever the current parent is an object
- Reuse the library's parser to generate streams where possible
- Contract-test custom emitters with nested structures
When it happens
Trigger: A stream where startArray appears inside an object context without a preceding key event.
Common situations: Buggy event producers; manually written event sequences omitting keys before nested arrays.
Related errors
- Object startObject event without preceding key
- Unexpected endObject event
- Mismatched endObject event
- Unexpected endArray event
- Mismatched endArray event
AI-assisted analysis of toon-format/toon@604eac266e (2026-08-31).
Data as JSON: /api/errors/7985e3d2f4bc11bf.
Report an issue: GitHub.