decolua/9router · error
Cursor AgentService request failed: ${error.message}
Error message
Cursor AgentService request failed: ${error.message} What it means
In passthroughHttp2, the native node:http2 client used to forward an intercepted HTTPS request to the upstream over HTTP/2 emits a connection-level error. The handler logs it, dumps it, replies 502 "Bad Gateway" to the client, and closes the client. It means the MITM proxy could not establish or maintain the h2 connection to the real server.
Source
Thrown at open-sse/executors/cursor.js:498
}
async executeAgent({ model, body, stream, credentials, signal }) {
const agentEndpoint = PROVIDER_OAUTH.cursor?.agentEndpoint;
if (!agentEndpoint) throw new Error("Cursor AgentService endpoint is not configured");
const url = `${agentEndpoint}${AGENT_RUN_PATH}`;
const headers = this.buildHeaders(credentials);
const requestController = new AbortController();
if (signal?.addEventListener) {
signal.addEventListener("abort", () => requestController.abort(signal.reason), { once: true });
}
let session;
try {
session = this.openAgentHttp2Stream(url, headers, requestController.signal);
session.write(buildAgentRunFrame(body.messages || [], model));
} catch (error) {
throw new Error(`Cursor AgentService request failed: ${error.message}`);
}
let responseHeaders;
try {
responseHeaders = await session.responseHeaders;
} catch (error) {
session.close();
throw new Error(`Cursor AgentService request failed: ${error.message}`);
}
const status = Number(responseHeaders[":status"] || 0);
if (status !== 200) {
let errorText = "";
try {
while (true) {
const { done, value } = await session.read();
if (done) break;
errorText += Buffer.from(value).toString("utf8");View on GitHub (pinned to 90b52e06ff)
Solutions
- Retry the request — many h2 session errors are transient.
- Check the log line `[mitm] http2 client error: <msg>` for the concrete cause (ECONNREFUSED, certificate, timeout).
- Verify DNS/hosts overrides used by resolveTargetIP are current (a MITM loop or stale /etc/hosts entry breaks the direct IP connection).
- Ensure no firewall requires an outbound HTTP proxy that the raw h2 connection bypasses.
- If the host keeps failing on h2, clear the ALPN cache or remove it so passthrough falls back to HTTP/1.1.
Defensive patterns
Strategy: retry
Validate before calling
// verify direct h2 reachability before routing through the MITM
tls.connect({ host: targetHost, port: 443, ALPNProtocols: ['h2'] }, function () {
if (this.alpnProtocol !== 'h2') console.warn('host will fall back to http/1.1');
this.end();
}).on('error', e => console.error('upstream unreachable:', e.message)); Try / catch
try {
await passthroughRequest(req);
} catch (e) {
if (e.status === 502 && /Bad Gateway/.test(await e.text())) {
// h2 connection to upstream failed — retry, then check logs for
// `[mitm] http2 client error: <msg>` and clear ALPN cache / fix DNS
}
} Prevention
- Retry 502s once before investigating — h2 session errors are often transient.
- Keep /etc/hosts and DNS overrides used for target IP resolution accurate.
- Ensure firewalls/AV don't block direct TLS to port 443 from the proxy process.
- Clear the ALPN cache if a host permanently fails on h2 so it falls back to HTTP/1.1.
When it happens
Trigger: ALPN negotiated "h2" for the host, passthrough() routed to passthroughHttp2, and http2.connect/tls.connect failed — TLS handshake failure, DNS/IP resolution returned a bad IP, connection refused/reset, or GOAWAY/session error before a response arrived.
Common situations: Corporate firewall or antivirus blocking direct TLS to port 443; resolveTargetIP pinned a stale IP; upstream temporarily rejecting h2; network flap mid-session; system proxy required but not used by the raw tls.connect.
Related errors
- [mitm] http2 client error: ${e.message}
- [mitm] http2 stream error: ${e.message}
- Passthrough error: ${e.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/800807fb93ffe7a2.
Report an issue: GitHub.