{"record":{"id":"dab3c39e69a4837f","repo":"decolua/9router","slug":"copilot-error-message","errorCode":null,"errorMessage":"[copilot] ${error.message}","messagePattern":"\\[copilot\\] (.+?)","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"src/mitm/handlers/copilot.js","lineNumber":29,"sourceCode":"function resolveRouterPath(reqUrl) {\n  for (const [pattern, routerPath] of Object.entries(URL_MAP)) {\n    if (reqUrl.includes(pattern)) return routerPath;\n  }\n  return \"/v1/chat/completions\";\n}\n\n/**\n * Intercept Copilot request — replace model and forward to matching 9Router endpoint\n */\nasync function intercept(req, res, bodyBuffer, mappedModel) {\n  try {\n    const body = JSON.parse(bodyBuffer.toString());\n    body.model = mappedModel;\n    const routerPath = resolveRouterPath(req.url);\n    const routerRes = await fetchRouter(body, routerPath, req.headers);\n    await pipeSSE(routerRes, res);\n  } catch (error) {\n    err(`[copilot] ${error.message}`);\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\nmodule.exports = { intercept };\n","sourceCodeStart":11,"sourceCodeEnd":36,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/src/mitm/handlers/copilot.js#L11-L36","documentation":"The copilot MITM handler remaps the model, resolves the router path from the incoming URL, forwards to the local router and pipes SSE back. Any exception is logged '[copilot] <message>' and returned to the client as a 500 JSON body with type 'mitm_error'.","triggerScenarios":"intercept() fails on JSON.parse of the request body, resolveRouterPath on an unexpected URL, fetchRouter connection refused (gateway down), or pipeSSE stream failure.","commonSituations":"GitHub Copilot CLI/extension pointed at the MITM port while the 9Router server is stopped; copilot sends an endpoint path the router doesn't expose; unauthenticated or malformed copilot request bodies.","solutions":["Start the 9Router gateway and confirm the MITM target port matches it.","Inspect the mitm_error message: ECONNREFUSED → gateway down; JSON errors → body format issue.","Verify the copilot tool's request URL maps to a supported router path.","Re-check the copilot connection credentials in the dashboard if the router returns 401."],"exampleFix":"// before\ncurl -x http://127.0.0.1:MITM_PORT https://api.githubcopilot.com/...  # gateway down → mitm_error\n// after\nPORT=20128 npm run start && curl -x http://127.0.0.1:MITM_PORT https://api.githubcopilot.com/...","handlingStrategy":"try-catch","validationCode":"const health = await fetch('http://127.0.0.1:20128/dashboard').then(r => r.ok).catch(() => false);\nif (!health) throw new Error('Router gateway not reachable');\nconst body = JSON.parse(bodyBuffer.toString());\nif (!body.model) throw new Error('Request body missing model field');","typeGuard":null,"tryCatchPattern":"try {\n  const routerRes = await fetchRouter(body, resolveRouterPath(req.url), req.headers);\n  await pipeSSE(routerRes, res);\n} catch (error) {\n  err(`[copilot] ${error.message}`);\n  if (!res.headersSent) res.writeHead(500, { 'Content-Type': 'application/json' });\n  res.end(JSON.stringify({ error: { message: error.message, type: 'mitm_error' } }));\n}","preventionTips":["Run a gateway health check before launching the MITM server.","Keep copilot connection credentials refreshed in the dashboard.","Log and review mitm_error responses for repeated path-mapping failures.","Update the router-path resolver when Copilot adds new endpoint paths."],"tags":["mitm","proxy","copilot","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"}