{"record":{"id":"eca5b4e8a0ce2d54","repo":"decolua/9router","slug":"binary-eventstream-format-detected-bodybuffer-l","errorCode":null,"errorMessage":"Binary EventStream format detected (${bodyBuffer.length}B) - request should use passthrough instead of intercept","messagePattern":"Binary EventStream format detected \\((.+?)B\\) - request should use passthrough instead of intercept","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/mitm/handlers/kiro.js","lineNumber":493,"sourceCode":" * Intercept Kiro IDE CodeWhisperer request and convert to EventStream response:\n *   1. Parse CodeWhisperer JSON body (reject binary EventStream formats)\n *   2. Convert CodeWhisperer format to OpenAI messages[] format\n *   3. Forward to 9router /v1/chat/completions (OpenAI SSE)\n *   4. Convert OpenAI SSE response → AWS EventStream binary frames\n *   5. Stream EventStream frames back to Kiro IDE\n * \n * @param {http.IncomingMessage} req - HTTP request from Kiro IDE\n * @param {http.ServerResponse} res - HTTP response to Kiro IDE  \n * @param {Buffer} bodyBuffer - Request body buffer\n * @param {string} mappedModel - Model name after MITM alias mapping\n */\nasync function intercept(req, res, bodyBuffer, mappedModel) {\n  try {\n    // Detect and handle binary data (e.g., continuation requests with EventStream frames)\n    if (isBinaryEventStream(bodyBuffer)) {\n      // Binary EventStream requests are typically continuation/streaming frames\n      // that don't contain model info - pass them through directly to avoid JSON.parse crash\n      throw new Error(`Binary EventStream format detected (${bodyBuffer.length}B) - request should use passthrough instead of intercept`);\n    }\n    \n    const body = JSON.parse(bodyBuffer.toString());\n\n    // 1 + 2: CodeWhisperer → OpenAI messages + tools\n    const messages = codeWhispererToMessages(body);\n    if (messages.length === 0) {\n      throw new Error(\"codeWhispererToMessages produced 0 messages — check request body\");\n    }\n\n    const tools = extractTools(body);\n\n    const openaiBody = {\n      model: mappedModel,\n      messages,\n      stream: true,\n      // Forward tools so Claude uses structured tool_calls instead of XML text fallback\n      ...(tools.length > 0 && { tools, tool_choice: \"auto\" }),","sourceCodeStart":475,"sourceCodeEnd":511,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/src/mitm/handlers/kiro.js#L475-L511","documentation":"The Kiro MITM intercept handler only accepts JSON request bodies (it JSON.parses bodyBuffer and translates CodeWhisperer format to OpenAI). Kiro continuation/streaming requests use AWS EventStream binary framing, which cannot be parsed — the library deliberately throws this error telling the caller such requests must take the passthrough path (direct proxy to upstream) instead of intercept. It is a routing-contract guard, not a parse crash.","triggerScenarios":"A request whose body isBinaryEventStream() detects EventStream framing (typically a Kiro continuation frame with no model info) is routed into intercept() instead of the passthrough handler — usually because the MITM routing decision was made before the body was inspected.","commonSituations":"Long-running Kiro CodeWhisperer sessions emitting continuation frames mid-stream; a reverse-proxy or upstream retry re-routing a continuation request to the intercept endpoint; version mismatch where the client now sends binary frames for a request type previously JSON.","solutions":["Route the request through the passthrough handler when isBinaryEventStream(bodyBuffer) is true, before calling intercept","Check the caller/dispatcher logic so binary detection happens before choosing intercept vs passthrough","If you control the client, avoid sending continuation frames to the intercept endpoint","Update the MITM proxy version — newer builds may auto-detect and forward binary frames"],"exampleFix":"// before\nawait intercept(req, res, bodyBuffer, mappedModel);\n// after\nif (isBinaryEventStream(bodyBuffer)) {\n  return passthrough(req, res, bodyBuffer);\n}\nawait intercept(req, res, bodyBuffer, mappedModel);","handlingStrategy":"validation","validationCode":"const { isBinaryEventStream } = require('./kiro');\nif (isBinaryEventStream(bodyBuffer)) {\n  return passthrough(req, res, bodyBuffer); // never call intercept with binary frames\n}\nawait intercept(req, res, bodyBuffer, mappedModel);","typeGuard":"function isJsonRequestBody(buf) {\n  return Buffer.isBuffer(buf) && !isBinaryEventStream(buf);\n}","tryCatchPattern":"try {\n  await intercept(req, res, bodyBuffer, mappedModel);\n} catch (e) {\n  if (/Binary EventStream format detected/.test(e.message)) {\n    return passthrough(req, res, bodyBuffer);\n  }\n  throw e;\n}","preventionTips":["Inspect the raw body with isBinaryEventStream before choosing intercept vs passthrough","Never JSON.parse request bodies without a binary check first","Keep the proxy updated for new Kiro framing behavior","Route continuation/streaming frames to passthrough by design"],"tags":["kiro","binary","eventstream","mitm","routing"],"backgroundTag":"binary-body-not-supported","analyzedSha":"90b52e06ffd666b7929554211474d01588f6b1f8","analyzedAt":"2026-08-30T21:05:45.952Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}