toon-format/toon · error · Error
Key event outside of object context
Error message
Key event outside of object context
What it means
applyEvent received a key event while the stack is empty — no object is open, so the key has nowhere to belong. Keys are only valid inside an object context.
Source
Thrown at packages/toon/src/decode/event-builder.ts:138
if (stack.length === 0) {
throw new Error('Unexpected endArray event')
}
const context = stack.pop()!
if (context.type !== 'array') {
throw new Error('Mismatched endArray event')
}
if (stack.length === 0) {
state.root = context.arr
}
break
}
case 'key': {
if (stack.length === 0) {
throw new Error('Key event outside of object context')
}
const parent = stack[stack.length - 1]!
if (parent.type !== 'object') {
throw new Error('Key event outside of object context')
}
parent.currentKey = event.key
break
}
case 'primitive': {
if (stack.length === 0) {
state.root = event.value
}
else {
const parent = stack[stack.length - 1]!View on GitHub (pinned to 604eac266e)
Solutions
- Emit startObject before any key events
- Fix the producer so keys only occur inside object contexts
- Pre-validate that key events are nested in an open object
Example fix
// before
[{type:'key',key:'a'},{type:'string',value:'x'}]
// after
[{type:'startObject'},{type:'key',key:'a'},{type:'string',value:'x'},{type:'endObject'}] Defensive patterns
Strategy: validation
Validate before calling
function keysOnlyInsideObject(events) {
let objectDepth = 0
for (const ev of events) {
if (ev.type === 'startObject') objectDepth++
else if (ev.type === 'endObject') objectDepth--
else if (ev.type === 'key' && objectDepth === 0) return false
}
return objectDepth === 0
} Try / catch
try {
const value = buildValueFromEvents(events)
} catch (e) {
if (e.message === 'Key event outside of object context') {
throw new Error('Event stream emitted a key with no open object')
}
throw e
} Prevention
- Open a startObject before emitting any key at stream start
- Never emit keys after the final endObject
- Validate key nesting in the producer before handing off to the builder
When it happens
Trigger: A key event before any startObject, or after all contexts have closed, fed to buildValueFromEvents/Async.
Common situations: Producers emitting top-level keys; streams missing an initial startObject.
Related errors
- Object startObject event without preceding key
- Unexpected endObject event
- Mismatched endObject event
- Array startArray event without preceding key
- Unexpected endArray event
AI-assisted analysis of toon-format/toon@604eac266e (2026-08-31).
Data as JSON: /api/errors/947ef23f1728fce3.
Report an issue: GitHub.