decolua/9router · error
http2 module not available
Error message
http2 module not available
What it means
Catch-all in the Copilot MITM handler: after mapping the model and forwarding the request via fetchRouter to the local 9Router /v1 endpoint, any thrown error (fetch failure, non-OK router response, SSE pipe error) is returned to the IDE as HTTP 500 JSON with type "mitm_error". The real cause is in error.message and the log line `[copilot] ...`.
Source
Thrown at open-sse/executors/cursor.js:327
async makeFetchRequest(url, headers, body, signal, proxyOptions = null) {
const response = await proxyAwareFetch(url, {
method: "POST",
headers,
body,
signal
}, proxyOptions);
return {
status: response.status,
headers: Object.fromEntries(response.headers.entries()),
body: Buffer.from(await response.arrayBuffer())
};
}
makeHttp2Request(url, headers, body, signal) {
if (!http2) {
throw new Error("http2 module not available");
}
const HTTP2_TIMEOUT_MS = 60000; // 60s max — prevent hung sessions
return new Promise((resolve, reject) => {
const urlObj = new URL(url);
const client = http2.connect(`https://${urlObj.host}`);
const chunks = [];
let responseHeaders = {};
let settled = false;
// Ensure client is always closed on settle
const finish = (fn) => (...args) => {
if (settled) return;
settled = true;
clearTimeout(hangTimeout);
client.close();
fn(...args);View on GitHub (pinned to 90b52e06ff)
Solutions
- Check the server log for `[copilot] <message>` to see the underlying cause.
- Ensure the 9Router gateway is running and the MITM proxy points at the correct LOCAL_PORT.
- Verify the model name in the Copilot request maps to a model the router can serve (model mapping config).
- Test the same prompt directly against the router's /v1 endpoint (curl) to isolate MITM vs router failure.
- Retry; transient fetch/SSE failures will resolve once connectivity is restored.
Defensive patterns
Strategy: retry
Validate before calling
const routerUp = await fetch(`http://localhost:${LOCAL_PORT}/dashboard`).then(r => r.ok).catch(() => false);
if (!routerUp) throw new Error('Start 9Router before routing Copilot traffic through the MITM proxy'); Try / catch
try {
const res = await sendViaCopilotMitm(body);
} catch (e) {
// mitm_error 500 — check `[copilot] <msg>` in server logs, retry once after
// confirming the gateway is reachable on LOCAL_PORT
} Prevention
- Confirm the router /v1 endpoint answers before enabling Copilot MITM routing.
- Ensure Copilot's requested model exists in the router's model mapping.
- Watch `[copilot]` log lines to catch recurring forwarding failures early.
- Keep LOCAL_PORT/proxy env consistent between the proxy and the gateway.
When it happens
Trigger: GitHub Copilot sends a chat request intercepted by the MITM proxy; resolveRouterPath/fetchRouter throws — e.g. the router is down, the route path is wrong, the request body is rejected upstream, or pipeSSE fails mid-stream.
Common situations: Router process not started; wrong LOCAL_PORT/proxy configuration; Copilot request uses a model that the router rejects; credentials missing on the router side; connection reset while streaming.
Related errors
- [copilot] ${error.message}
- Machine ID is required for Cursor API
- Cursor AgentService endpoint is not configured
- [antigravity] ${error.message}
- HTTP/2 is required for Cursor AgentService (endpoint is h2-o
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/26b2b69201c41e47.
Report an issue: GitHub.