{"record":{"id":"947ef23f1728fce3","repo":"toon-format/toon","slug":"key-event-outside-of-object-context","errorCode":null,"errorMessage":"Key event outside of object context","messagePattern":"Key event outside of object context","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/toon/src/decode/event-builder.ts","lineNumber":138,"sourceCode":"      if (stack.length === 0) {\n        throw new Error('Unexpected endArray event')\n      }\n\n      const context = stack.pop()!\n      if (context.type !== 'array') {\n        throw new Error('Mismatched endArray event')\n      }\n\n      if (stack.length === 0) {\n        state.root = context.arr\n      }\n\n      break\n    }\n\n    case 'key': {\n      if (stack.length === 0) {\n        throw new Error('Key event outside of object context')\n      }\n\n      const parent = stack[stack.length - 1]!\n      if (parent.type !== 'object') {\n        throw new Error('Key event outside of object context')\n      }\n\n      parent.currentKey = event.key\n\n      break\n    }\n\n    case 'primitive': {\n      if (stack.length === 0) {\n        state.root = event.value\n      }\n      else {\n        const parent = stack[stack.length - 1]!","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/toon-format/toon/blob/604eac266e35166bed6f5b9e3bd586e9c60a9330/packages/toon/src/decode/event-builder.ts#L120-L156","documentation":"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.","triggerScenarios":"A key event before any startObject, or after all contexts have closed, fed to buildValueFromEvents/Async.","commonSituations":"Producers emitting top-level keys; streams missing an initial startObject.","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"],"exampleFix":"// before\n[{type:'key',key:'a'},{type:'string',value:'x'}]\n// after\n[{type:'startObject'},{type:'key',key:'a'},{type:'string',value:'x'},{type:'endObject'}]","handlingStrategy":"validation","validationCode":"function keysOnlyInsideObject(events) {\n  let objectDepth = 0\n  for (const ev of events) {\n    if (ev.type === 'startObject') objectDepth++\n    else if (ev.type === 'endObject') objectDepth--\n    else if (ev.type === 'key' && objectDepth === 0) return false\n  }\n  return objectDepth === 0\n}","typeGuard":null,"tryCatchPattern":"try {\n  const value = buildValueFromEvents(events)\n} catch (e) {\n  if (e.message === 'Key event outside of object context') {\n    throw new Error('Event stream emitted a key with no open object')\n  }\n  throw e\n}","preventionTips":["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"],"tags":["event-stream","decoder","toon"],"backgroundTag":"malformed-event-stream","analyzedSha":"604eac266e35166bed6f5b9e3bd586e9c60a9330","analyzedAt":"2026-08-31T11:09:25.043Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}