Nested run accepts then starves before first content event

Where does the bug appear (feature/product)?

Cursor SDK

Describe the Bug

I embed @cursor/sdk for nested delegations. Three unrelated nested runs across two models were accepted (request + RUNNING within 85ms) then emitted zero content events for 407-425s before failing with Connection failed repeatedly after ten aborted streaming attempts with backoff. A full server restart did not clear it. Healthy finished runs always produce a content event (p99 77.91s, max 165.56s); these never did.

Steps to Reproduce

Aug 6, 18:32-19:06 UTC, three nested delegate runs in unrelated conversations:

  1. 18:32:53, grok-4.5, 425.3s, implementing-cache-sdk-checkpoint-store
  2. 18:35:46, grok-4.5, 411.0s, auto-planning
  3. 18:36:22, claude-opus-5, 407.4s, auto-planning-more-chat-enhancements
    Each: request + RUNNING <85ms, then silence in run_events.ndjson until Connection failed repeatedly. Full server restart between attempts did not help.

Expected Behavior

After RUNNING, the SDK should stream content events or fail fast with a structured error, not hang ~7 minutes with no tokens.

Version Information

@cursor/sdk ^1.0.27, Node v22.22.1, linux 6.12.67-linuxkit. Models: grok-4.5, claude-opus-5. Nested delegate bridge.

Hey, thanks for the detailed report, the timestamps and numbers really help. I’ll break it into two parts.

  1. About the ~7 minutes of silence and Connection failed repeatedly after 10 attempts. That’s the current SDK retry behavior. Each reconnect attempt hits the stall timeout which is about 30s without incoming data, plus a backoff between attempts. That adds up to the ~400 to 425 seconds you measured. The fact that you don’t get any intermediate run events and it doesn’t fail fast with a structured error, and instead you just see a long silence, is a known observability limitation in the SDK. The team is aware, but I can’t share an ETA.

  2. The root cause of the starvation RUNNING but zero content events. Based on what we have, this looks like a drop of a long lived HTTP/2 bidirectional stream somewhere on the network path. Your version info shows linuxkit, so this is running in a Docker container. Agent runs use a bidi HTTP/2 stream, and in containers or behind proxies these long streams often get silently dropped by NAT or proxy idle timeouts. Unary calls like Agent.create and models.list still work, but the stream hangs. The fact that all three runs were concurrent, across two different models, and a restart didn’t help, fits a short lived egress path issue that later fixed itself.

What would help us dig deeper:

  • Request ID for each failed attempt. The SDK logs a requestId per attempt. Without those we can’t match the runs on the backend. Under the account that created the thread we don’t see activity, so it looks like the SDK might be using a different API key. Please confirm which account and key it’s actually using.
  • Check egress idle timeouts in Docker or your proxy for the Cursor API endpoints. In container setups this is a common cause of long stream drops.
  • You can try an HTTP/1.1 fallback, with a caveat. On some SDK versions it’s still unstable and can fail with unsupported content type text/event-stream. If you see that, switch back to HTTP/2 and focus on proxy or container idle timeouts instead. Context here: https://forum.cursor.com/t/cursor-sdk-with-http-1-1/159868

Send the Request IDs and we can check whether the runs reached the backend or if the drop happened on the network path.