{"record":{"id":"d2e97c862c799137","repo":"decolua/9router","slug":"machine-id-is-required-for-cursor-api","errorCode":null,"errorMessage":"Machine ID is required for Cursor API","messagePattern":"Machine ID is required for Cursor API","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"open-sse/executors/cursor.js","lineNumber":292,"sourceCode":"  });\n}\n\nexport class CursorExecutor extends BaseExecutor {\n  constructor() {\n    super(\"cursor\", PROVIDERS.cursor);\n  }\n\n  buildUrl() {\n    return `${this.config.baseUrl}${this.config.chatPath}`;\n  }\n\n  buildHeaders(credentials) {\n    const accessToken = credentials.accessToken;\n    const machineId = credentials.providerSpecificData?.machineId;\n    const ghostMode = credentials.providerSpecificData?.ghostMode !== false;\n\n    if (!machineId) {\n      throw new Error(\"Machine ID is required for Cursor API\");\n    }\n\n    return buildCursorHeaders(accessToken, machineId, ghostMode);\n  }\n\n  transformRequest(model, body, stream, credentials) {\n    // Messages are already translated by chatCore (claude→openai→cursor)\n    // Do NOT call openaiToCursorRequest again — double-translation drops tool_results\n    const messages = body.messages || [];\n    const tools = body.tools || [];\n    const reasoningEffort = body.reasoning_effort || null;\n    // Detect Claude Code UA to force Agent mode (issue #643)\n    const ua = credentials?.rawHeaders?.[\"user-agent\"] || \"\";\n    const forceAgentMode = ua.includes(\"claude-cli\") || ua.includes(\"claude-code\") || ua.includes(\"Claude Code\");\n    return generateCursorBody(messages, model, tools, reasoningEffort, forceAgentMode);\n  }\n\n  async makeFetchRequest(url, headers, body, signal, proxyOptions = null) {","sourceCodeStart":274,"sourceCodeEnd":310,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/open-sse/executors/cursor.js#L274-L310","documentation":"Generic catch-all inside the Antigravity MITM handler: when re-routing an intercepted request to the 9Router throws for any reason, the handler echoes the underlying error.message back to the IDE client. If the original request was streaming, it returns a synthetic SSE error chunk (HTTP 200) so the SDK does not hang; otherwise it returns HTTP 500 JSON with type \"mitm_error\".","triggerScenarios":"The Antigravity IDE sends a chat/stream request through the MITM proxy, the host maps to the antigravity tool, a model mapping exists, and the call to handlers.antigravity.intercept throws (router fetch failure, body parse failure, upstream error propagation) before the handler completes.","commonSituations":"9Router backend not running or crashing while the MITM proxy still intercepts traffic; invalid mapped model; network/DNS failure reaching the local router; exception thrown while reading the intercepted body.","solutions":["Verify the 9Router server (dashboard/gateway on the configured LOCAL_PORT) is running and reachable — the MITM handler forwards to it.","Check the MITM proxy logs / dumper output for the underlying [ERROR] message to identify the real failure.","Confirm the model used by the IDE has a valid entry in the antigravity model mapping (getMappedModel); unmapped models pass through instead.","Retry the request; transient router/upstream failures surface as this 500.","If it persists, bypass the MITM proxy for Antigravity traffic (remove proxy env) until the router issue is fixed."],"exampleFix":"// before: client hangs or gets opaque 500\nres.end(JSON.stringify({ error: { message: error.message, type: \"mitm_error\" } }));\n// after: inspect root cause by logging full stack in the handler catch\nerr(`[antigravity] ${error.stack}`);\nres.end(JSON.stringify({ error: { message: error.message, type: \"mitm_error\" } }));","handlingStrategy":"try-catch","validationCode":"// before relying on MITM routing, check the router is up\nconst health = await fetch(`http://localhost:${LOCAL_PORT}/dashboard`).catch(() => null);\nif (!health || !health.ok) throw new Error('9Router gateway is not running; disable MITM proxy or start it');","typeGuard":null,"tryCatchPattern":"try {\n  await sendThroughMitm(request);\n} catch (e) {\n  if (String(e.message).includes('mitm_error') || /ECONNREFUSED|fetch failed/.test(e.message)) {\n    // router down — bypass proxy or restart 9Router, then retry once\n  } else throw e;\n}","preventionTips":["Keep the 9Router gateway running whenever the system/browser proxy points at the MITM port.","Monitor the gateway health endpoint (/_mitm_health on the MITM server) before sending traffic.","Keep model mappings current so intercepted models always resolve.","Check the dumper/log output when a 500 mitm_error appears — the inner message names the real cause."],"tags":["mitm","proxy","antigravity","internal-server-error"],"backgroundTag":"mitm-proxy-intercept-failure","analyzedSha":"90b52e06ffd666b7929554211474d01588f6b1f8","analyzedAt":"2026-08-30T21:05:45.952Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}