{"record":{"id":"8775c0854e2d0458","repo":"decolua/9router","slug":"antigravity-error-message","errorCode":null,"errorMessage":"[antigravity] ${error.message}","messagePattern":"\\[antigravity\\] (.+?)","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"src/mitm/handlers/antigravity.js","lineNumber":20,"sourceCode":"const { IS_DEV } = require(\"../config\");\nconst { fetchRouter, pipeSSE } = require(\"./base\");\n\n/**\n * Intercept Antigravity request — forward Gemini body as-is to /v1/chat/completions.\n * Router auto-detects format via body.userAgent===\"antigravity\" + body.request.contents,\n * runs antigravity→openai→provider→openai→antigravity translators internally.\n */\nasync function intercept(req, res, bodyBuffer, mappedModel) {\n  const dumper = IS_DEV ? createResponseDumper(req, \"intercept-antigravity\") : null;\n  const isStream = req.url.includes(\":streamGenerateContent\");\n  try {\n    const body = JSON.parse(bodyBuffer.toString());\n    if (body.model) body.model = mappedModel;\n\n    const routerRes = await fetchRouter(body, \"/v1/chat/completions\", req.headers);\n    await pipeSSE(routerRes, res, dumper);\n  } catch (error) {\n    err(`[antigravity] ${error.message}`);\n    if (dumper) { dumper.writeChunk(`\\n[ERROR] ${error.message}\\n`); dumper.end(); }\n    // For stream endpoint, send SSE error chunk so SDK doesn't hang waiting\n    if (isStream) {\n      if (!res.headersSent) res.writeHead(200, { \"Content-Type\": \"text/event-stream\" });\n      res.end(`data: ${JSON.stringify({ error: { message: error.message } })}\\r\\n\\r\\n`);\n    } else {\n      if (!res.headersSent) res.writeHead(500, { \"Content-Type\": \"application/json\" });\n      res.end(JSON.stringify({ error: { message: error.message, type: \"mitm_error\" } }));\n    }\n  }\n}\n\nmodule.exports = { intercept };\n","sourceCodeStart":2,"sourceCodeEnd":34,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/src/mitm/handlers/antigravity.js#L2-L34","documentation":"The antigravity MITM handler intercepts requests, remaps the model, forwards the body to the local router's /v1/chat/completions, and pipes the SSE response back. Any failure in that pipeline (body parse, model mapping, router fetch, SSE piping) is logged as '[antigravity] <message>'; for stream requests it emits an SSE error chunk so the SDK does not hang, otherwise a JSON error response.","triggerScenarios":"intercept() called with malformed JSON body (JSON.parse throws), router not running on the local port (fetchRouter fails), model name with no mapping, or the SSE stream from the router aborts mid-pipe.","commonSituations":"Tool configured to point at the MITM proxy before `9router` server is started; antigravity CLI updated to a model id the mapper doesn't know; request body format changed upstream.","solutions":["Verify the 9Router gateway is running on the port the MITM proxy forwards to (default 20128).","Check the error message in the dump file / logs — JSON parse errors mean the tool sent a non-JSON body; router errors mean check the router's own logs.","Confirm the requested model has a mapping in the model-map config for antigravity.","Retry the request; transient SSE disconnects are surfaced here but are often upstream-side."],"exampleFix":"// before: router not running\nfetch http://127.0.0.1:20128/v1/chat/completions -> ECONNREFUSED\n// after: start the gateway first\nPORT=20128 npm run start  # then retry the tool request","handlingStrategy":"try-catch","validationCode":"// before routing, verify the gateway is up\nconst health = await fetch('http://127.0.0.1:20128/dashboard').then(r => r.ok).catch(() => false);\nif (!health) throw new Error('Router gateway not running on :20128');\nJSON.parse(bodyBuffer.toString()); // fail fast on malformed body","typeGuard":null,"tryCatchPattern":"try {\n  const routerRes = await fetchRouter(body, '/v1/chat/completions', req.headers);\n  await pipeSSE(routerRes, res, dumper);\n} catch (error) {\n  err(`[antigravity] ${error.message}`);\n  if (isStream && !res.headersSent) {\n    res.writeHead(200, { 'Content-Type': 'text/event-stream' });\n    res.end(`data: ${JSON.stringify({ error: { message: error.message } })}\\r\\n\\r\\n`);\n  }\n}","preventionTips":["Always start the 9Router gateway before pointing tools at the MITM proxy.","Keep model mappings for antigravity up to date with the tool's model ids.","Monitor the MITM dump file for recurring [ERROR] chunks.","Health-check the gateway port in startup scripts."],"tags":["mitm","proxy","sse","router-unreachable"],"backgroundTag":"mitm-proxy-request-failed","analyzedSha":"90b52e06ffd666b7929554211474d01588f6b1f8","analyzedAt":"2026-08-30T21:05:45.952Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}