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

  1. Retry the request — many h2 session errors are transient.
  2. Check the log line `[mitm] http2 client error: <msg>` for the concrete cause (ECONNREFUSED, certificate, timeout).
  3. Verify DNS/hosts overrides used by resolveTargetIP are current (a MITM loop or stale /etc/hosts entry breaks the direct IP connection).
  4. Ensure no firewall requires an outbound HTTP proxy that the raw h2 connection bypasses.
  5. 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

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


AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30). Data as JSON: /api/errors/800807fb93ffe7a2. Report an issue: GitHub.