decolua/9router · error · Error

codeWhispererToMessages produced 0 messages — check request

Error message

codeWhispererToMessages produced 0 messages — check request body

What it means

After JSON-parsing the Kiro/CodeWhisperer request, intercept() converts it to OpenAI-style messages via codeWhispererToMessages(). If that converter yields an empty array, there is nothing to forward upstream, so the handler throws this error rather than sending a doomed request. It signals the request body had a shape the translator did not recognize or contained no conversation content.

Source

Thrown at src/mitm/handlers/kiro.js:501

 * @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" }),
    };

    // 3: Forward to 9router
    const routerRes = await fetchRouter(openaiBody, "/v1/chat/completions", req.headers);

    // 4 + 5: Re-encode response as AWS EventStream binary using standard pipeline
    const state = initKiroState(mappedModel);

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Log the parsed body (JSON.stringify(body)) and compare its shape against what codeWhispererToMessages expects in the translator
  2. Ensure the request includes populated conversation state (history + current message) before routing to intercept
  3. Update the proxy/translator to the client's current CodeWhisperer schema if the client was upgraded
  4. Verify the request is actually a Kiro/CodeWhisperer conversation and not another tool's request misrouted to this handler

Example fix

// before
const body = JSON.parse(rawBody);
await intercept(req, res, rawBody, model);
// after
const body = JSON.parse(rawBody);
const msgs = codeWhispererToMessages(body);
if (!msgs.length) {
  console.error('untranslated body:', JSON.stringify(body).slice(0, 500));
  return res.status(400).end('empty conversation');
}
Defensive patterns

Strategy: validation

Validate before calling

const msgs = codeWhispererToMessages(body);
if (!Array.isArray(msgs) || msgs.length === 0) {
  return res.status(400).json({ error: 'Request contained no translatable conversation' });
}

Type guard

function hasTranslatableMessages(body) {
  const msgs = codeWhispererToMessages(body);
  return Array.isArray(msgs) && msgs.length > 0;
}

Try / catch

try {
  await intercept(req, res, bodyBuffer, mappedModel);
} catch (e) {
  if (e.message.includes('produced 0 messages')) {
    console.error('Body failed translation:', bodyBuffer.toString().slice(0, 500));
    return res.status(400).end();
  }
  throw e;
}

Prevention

When it happens

Trigger: POSTing to the Kiro intercept endpoint a body that JSON-parses but has no recognizable CodeWhisperer conversation fields — e.g. `{}`, an empty `conversationState`, missing `currentMessage`/history entries, or a body whose structure changed in a newer client version the translator does not yet map.

Common situations: Client app updated and changed the CodeWhisperer request schema ahead of the proxy's translator; a tool sent an empty/keepalive JSON body through the intercept path; manual curl tests with hand-written minimal bodies; a non-Kiro request mistakenly routed to the Kiro handler.

Related errors


AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30). Data as JSON: /api/errors/588008d9318a00cb. Report an issue: GitHub.