{"record":{"id":"4a59e0756f266e1e","repo":"can1357/oh-my-pi","slug":"v2-compaction-stream-parse-failed-err-instanceo","errorCode":null,"errorMessage":"V2 compaction stream parse failed: ${err instanceof Error ? err.message : String(err)}","messagePattern":"V2 compaction stream parse failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/agent/src/compaction/compaction-v2-streaming.ts","lineNumber":562,"sourceCode":"\t\tcompactionItem,\n\t\treplacementHistory,\n\t\tusedTokens: state.usage?.inputTokens ?? 0,\n\t\tusage: state.usage,\n\t\tretainedImageCount,\n\t};\n}\n\nfunction handleCompactionV2SseEvent(\n\tdata: string,\n\teventName: string | undefined,\n\tstate: CompactionV2CollectionState,\n): void {\n\tif (data === \"[DONE]\") return;\n\tlet event: Record<string, unknown>;\n\ttry {\n\t\tevent = JSON.parse(data) as Record<string, unknown>;\n\t} catch (err) {\n\t\tthrow new Error(`V2 compaction stream parse failed: ${err instanceof Error ? err.message : String(err)}`);\n\t}\n\thandleCompactionV2Event(event, eventName, state);\n}\n\nfunction handleCompactionV2Event(\n\tevent: Record<string, unknown>,\n\teventName: string | undefined,\n\tstate: CompactionV2CollectionState,\n): void {\n\tconst type = typeof event.type === \"string\" ? event.type : eventName;\n\tif (type === \"response.output_item.done\") {\n\t\tstate.outputItemCount++;\n\t\tconst item = event.item;\n\t\tif (isRecord(item) && item.type === \"compaction\") {\n\t\t\tstate.compactionItems.push(item);\n\t\t}\n\t\treturn;\n\t}","sourceCodeStart":544,"sourceCodeEnd":580,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/agent/src/compaction/compaction-v2-streaming.ts#L544-L580","documentation":"A SSE data frame from the V2 compaction stream failed JSON.parse (and was not the literal [DONE] sentinel). The parse error message is embedded and rethrown so the failure points at the actual malformed frame rather than crashing deep in event handling.","triggerScenarios":"The endpoint (or an intermediary proxy) emits a data line that is not valid JSON — e.g. an HTML error page chunk, a plain-text gateway error, truncated JSON from a dropped connection, or multi-frame data split/reassembled incorrectly by a proxy.","commonSituations":"Auth proxies returning HTML 'login required' bodies with 200; CDN/WAF injecting error text mid-stream; keep-alive comments misinterpreted as data; custom fetch wrappers mangling the byte stream (wrong decoding/chunk boundaries).","solutions":["Log the offending data frame (the embedded parse error / raw payload) to see what the server actually sent","Check for proxies/WAF/gateways injecting non-JSON content into the SSE stream and bypass or fix them","Ensure the response is consumed as a byte stream decoded incrementally (TextDecoder over reader chunks), not re-split incorrectly by custom plumbing","Retry the compaction; if it reproduces deterministically, verify you are hitting the compaction endpoint with valid auth"],"exampleFix":"// before\nconst text = await response.text(); text.split(\"\\n\") // mangles SSE frames\n// after\nconst reader = response.body!.getReader();\n// decode incrementally with TextDecoder and split on \\n\\n event boundaries","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  return await requestCompactionV2Streaming({ model, ... });\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith(\"V2 compaction stream parse failed\")) {\n    logRawSseFramesOnce(); // capture the offending frame\n    await Bun.sleep(backoff);\n    return requestCompactionV2Streaming({ model, ... });\n  }\n  throw err;\n}","preventionTips":["Bypass or fix proxies/WAFs that inject HTML/plain-text into SSE streams","Consume responses as incremental byte streams with TextDecoder; never re-split cached text","Retry transient parse failures; investigate persistent ones at the network layer"],"tags":["sse","json","parsing","streaming","compaction"],"backgroundTag":"invalid-json-response","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}