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
- Log the parsed body (JSON.stringify(body)) and compare its shape against what codeWhispererToMessages expects in the translator
- Ensure the request includes populated conversation state (history + current message) before routing to intercept
- Update the proxy/translator to the client's current CodeWhisperer schema if the client was upgraded
- 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
- Log and inspect the parsed body whenever translation fails
- Validate the request has conversation content before routing to the Kiro handler
- Keep the translator in sync with the client's CodeWhisperer schema version
- Reject empty/keepalive JSON bodies at the edge
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
- Cursor AgentService endpoint is not configured
- Binary EventStream format detected (${bodyBuffer.length}B) -
- [Kiro MITM] Request processing failed: ${error.message}
- Machine ID is required for Cursor API
- http2 module not available
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/588008d9318a00cb.
Report an issue: GitHub.