SDK Run POST of 18 MiB hits ENHANCE_YOUR_CALM and bricks conversation

Where does the bug appear (feature/product)?

Cursor SDK

Describe the Bug

My long-lived local agent accumulated ~46 MB of checkpoint state across 3,635 blobs. Each turn now POSTs 18.41 MiB to /agent.v1.AgentService/Run, over the ~11 MB HTTP/2 boundary. The server RST_STREAMs code 11 in ~100ms. The SDK retries the identical payload ten times, then reports Connection failed repeatedly. Skills can be deleted; conversation history cannot, so this conversation is permanently bricked. collectPreFetchedBlobs defaults maxTotalBytes to 33554432, roughly 3× the HTTP/2 limit, so the SDK builds requests that cannot succeed. The built-in task tool returns the subagent’s full transcript in conversationSteps; 32 task calls added 9.3 MB to the parent.

Steps to Reproduce

I resumed the stuck agent from a copy of its JsonlLocalAgentStore in a scratch cwd, with http2.connect patched to log per-stream bytes and rstCode:

request body complete: 18.41 MiB sent STREAM ERROR after 97ms, sent=18.41MiB recv=0B :: ERR_HTTP2_STREAM_ERROR NGHTTP2_ENHANCE_YOUR_CALM close rstCode=11

Ten identical attempts, 396s total, ending in Connection failed repeatedly — matching production at 402s and 395s. useHttp1ForAgent gave no clean 50 MB BAD_REQUEST here — 18.41 MiB is under that cap, so the request hung over 13 minutes.

Expected Behavior

Cap collectPreFetchedBlobs below the HTTP/2 limit rather than at 32 MiB. Treat ENHANCE_YOUR_CALM as non-retryable when the payload is unchanged, instead of ten identical re-sends. Give conversation state a compaction path, since unlike skills it cannot be pruned from disk. Surface the transport error on RunResult.

Version Information

@cursor/sdk 1.0.24; Node v20.11.0; Linux 6.12.67-linuxkit x86_64; local agents (mode agent, JsonlLocalAgentStore) embedded in a long-lived Node server; model id default; auth via dashboard user API key. Moved from Cursor-agent CLI: TUI fails with `NGHTTP2_ENHANCE_YOUR_CALM` once skill payload exceeds ~11 MB; no scoping option at Dean Rie’s request.

Hey James, thanks for such a detailed write-up, and for moving the SDK case into a separate thread.

Your analysis matches what we’re seeing. In @cursor/sdk versions up to and including 1.0.24, every Run request attached a bundle of conversation blobs as a cache-priming step, with a limit above what the transport accepts. Once the conversation history crossed that boundary, every request was guaranteed to be broken. That priming step was completely removed in SDK 1.0.25, and newer versions no longer attach blobs.

Can you update to the latest @cursor/sdk (as of today, 1.0.30) and resume the stuck agent? The on-disk store format hasn’t changed, so the same JsonlLocalAgentStore directory will keep working, and the conversation shouldn’t hit that wall anymore.

Your other points are also valid, retrying an identical payload that can’t succeed, surfacing transport errors on RunResult, and having a compaction path for long-lived conversations. I’ve passed those along to the team. Let me know how the upgrade goes.