decolua/9router · error · Error
Binary EventStream format detected (${bodyBuffer.length}B) -
Error message
Binary EventStream format detected (${bodyBuffer.length}B) - request should use passthrough instead of intercept What it means
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.
Source
Thrown at src/mitm/handlers/kiro.js:493
* Intercept Kiro IDE CodeWhisperer request and convert to EventStream response:
* 1. Parse CodeWhisperer JSON body (reject binary EventStream formats)
* 2. Convert CodeWhisperer format to OpenAI messages[] format
* 3. Forward to 9router /v1/chat/completions (OpenAI SSE)
* 4. Convert OpenAI SSE response → AWS EventStream binary frames
* 5. Stream EventStream frames back to Kiro IDE
*
* @param {http.IncomingMessage} req - HTTP request from Kiro IDE
* @param {http.ServerResponse} res - HTTP response to Kiro IDE
* @param {Buffer} bodyBuffer - Request body buffer
* @param {string} mappedModel - Model name after MITM alias mapping
*/
async function intercept(req, res, bodyBuffer, mappedModel) {
try {
// Detect and handle binary data (e.g., continuation requests with EventStream frames)
if (isBinaryEventStream(bodyBuffer)) {
// Binary EventStream requests are typically continuation/streaming frames
// that don't contain model info - pass them through directly to avoid JSON.parse crash
throw new Error(`Binary EventStream format detected (${bodyBuffer.length}B) - request should use passthrough instead of intercept`);
}
const body = JSON.parse(bodyBuffer.toString());
// 1 + 2: CodeWhisperer → OpenAI messages + tools
const messages = codeWhispererToMessages(body);
if (messages.length === 0) {
throw new Error("codeWhispererToMessages produced 0 messages — check request body");
}
const tools = extractTools(body);
const openaiBody = {
model: mappedModel,
messages,
stream: true,
// Forward tools so Claude uses structured tool_calls instead of XML text fallback
...(tools.length > 0 && { tools, tool_choice: "auto" }),View on GitHub (pinned to 90b52e06ff)
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
Example fix
// before
await intercept(req, res, bodyBuffer, mappedModel);
// after
if (isBinaryEventStream(bodyBuffer)) {
return passthrough(req, res, bodyBuffer);
}
await intercept(req, res, bodyBuffer, mappedModel); Defensive patterns
Strategy: validation
Validate before calling
const { isBinaryEventStream } = require('./kiro');
if (isBinaryEventStream(bodyBuffer)) {
return passthrough(req, res, bodyBuffer); // never call intercept with binary frames
}
await intercept(req, res, bodyBuffer, mappedModel); Type guard
function isJsonRequestBody(buf) {
return Buffer.isBuffer(buf) && !isBinaryEventStream(buf);
} Try / catch
try {
await intercept(req, res, bodyBuffer, mappedModel);
} catch (e) {
if (/Binary EventStream format detected/.test(e.message)) {
return passthrough(req, res, bodyBuffer);
}
throw e;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Cursor AgentService endpoint is not configured
- [Kiro MITM] Request processing failed: ${error.message}
- Kiro toolUseEvent is empty
- Kiro toolUseEvent is missing a tool name
- Kiro toolUseEvent has an invalid toolUseId
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/eca5b4e8a0ce2d54.
Report an issue: GitHub.