@cursor/sdk 1.0.31 local agent: Agent.create succeeds, agent.send() hangs with no stream (network to Cursor is healthy)

Where does the bug appear (feature/product)?

Cursor SDK

Describe the Bug

@cursor/sdk 1.0.31 local agent: Agent.create() returns in about 2 seconds, then agent.send() never resolves and never rejects. There is no run, no text, and no error. Our logs are written only after send() returns, so the await is still inside the SDK.

Earlier the same morning, fresh local agents did start, streamed tool calls, then the stream died with:

[unknown] [canceled] This operation was aborted
Those runs never finished. This is not a network outage: from the same host, HTTPS to the Cursor endpoints stayed healthy for a 6-minute probe (see Additional Information). No HTTP proxy. One Node process.

Steps to Reproduce

Environment:

@cursor/sdk: 1.0.31 (@cursor/sdk-linux-x64 1.0.31)
Node.js: v22.14.0
OS: Linux x86_64, kernel 4.18.0-553.137.1.el8_10
Runtime: local agent, model: { id: “auto” }
One process: node dist/index.js, listening on 127.0.0.1:9527
http_proxy / https_proxy / ALL_PROXY: unset
Call path after create:

const runs = await Agent.listRuns(agentId, { runtime: “local”, cwd, limit: 5 });
const run = await agent.send(message, options);
listRuns logs only on failure. send() logs only after it returns. Neither line was written, so the await is still inside the SDK.

Steps:

Start one long-lived Node 22 process using @cursor/sdk 1.0.31 with a local agent and model: { id: “auto” }.
Agent.create() succeeds in about 2 seconds.
Call Agent.listRuns(…), then agent.send(message, options).
Wait. send() does not return. No stream event is emitted for at least 10 minutes.
On other attempts the same morning, the stream starts, tool calls run, then it aborts with [unknown] [canceled] This operation was aborted.

Expected Behavior

agent.send() returns a Run and the stream emits status or text within a few seconds, or it rejects with a typed error (NetworkError, AuthenticationError, or a message other than a bare cancel).

Operating System

Linux

Version Information

Not the Cursor IDE, CLI, or iOS app. Headless local SDK:

@cursor/sdk: 1.0.31
@cursor/sdk-linux-x64: 1.0.31
Node.js: v22.14.0
Kernel: 4.18.0-553.137.1.el8_10 x86_64

For AI issues: which model did you use?

auto (model: { id: “auto” }, server-routed auto)

For AI issues: add Request ID with privacy disabled

No Request ID. agent.send() never returned a run, so the SDK did not give us a request id.
Agent ids from the hung attempt:

agent-096ea348-6478-48c5-a084-b90740657358 (created, then silent)
agent-5e9c4412-7d1f-4c36-ab0c-6964861072fe (retry 10 minutes later, also silent)

Additional Information

Network check on the same host, 20 rounds every 15 seconds, 02:23–02:29 UTC, 100 requests, 0 failures. 403 / 404 are unauthenticated GET / after TLS succeeded.

Host OK Fail min avg max HTTP
agentn.global.api5.cursor.sh
20
0
0.232s
0.262s
0.349s
200
api2.cursor.sh
20
0
0.726s
0.899s
2.466s
200
api.cursor.com
20
0
0.722s
0.875s
2.235s
200
authenticator.cursor.sh
20
0
0.367s
0.628s
0.849s
403
repo42.cursor.sh
20
0
0.727s
0.963s
4.056s
404

02:23:37 api2.cursor.sh code=200 dns=0.005672 connect=0.242637 tls=2.219924 total=2.466161
02:23:37 agentn.global.api5.cursor.sh code=200 dns=0.013823 connect=0.100604 tls=0.179530 total=0.255237
02:27:04 repo42.cursor.sh code=404 dns=0.042216 connect=3.342532 tls=3.583319 total=4.056254
02:29:33 agentn.global.api5.cursor.sh code=200 dns=0.009737 connect=0.082681 tls=0.174429 total=0.249867
SDK logs (CST, user and prompt text removed):

2026-10-23 09:11:xx ERROR stream ERROR raw status=ERROR message=“[unknown] [canceled] This operation was aborted”
2026-10-23 09:20:xx ERROR stream ERROR raw status=ERROR message=“[unknown] [canceled] This operation was aborted”
2026-10-23 09:38:41 INFO resolved cursor model requestedModel=auto resolvedModel=auto
2026-10-23 09:38:43 INFO created agent agentId=agent-096ea348-6478-48c5-a084-b90740657358 freshAgent=true
No run event, no text, no stream ERROR, no run finished for the next 10 minutes. Our HTTP idle-read timeout is 600 seconds, so the caller opened a new agent:

2026-10-23 09:48:46 INFO executor run input freshAgent=true model=auto
2026-10-23 09:48:47 INFO created agent agentId=agent-5e9c4412-7d1f-4c36-ab0c-6964861072fe
The second send() was also silent. Agent.create is fast. The stall is after create, before the first stream event.

Different from #161203 and #163819: those fail fast with a bare status=ERROR. Here send() does not return.

Does this stop you from using Cursor

Yes - Cursor is unusable

Hey, thanks for the detailed report. Having the agent ID and timeline makes this much easier to dig into.

I checked what happened with those two agents on our side. The send() call did eventually reach us, just much later: the runs started about 17 and 7 minutes after the agents were created, almost at the same time, and both finished normally in about a minute. It looks like both send() calls were waiting inside the SDK on one shared step that runs before the run starts, and they were both released together when that step finished. One possible cause is that the connection held by the process had died after a long idle period, but we haven’t confirmed that yet. In 1.0.31, there is no timeout in this part of send(). We’re tracking this issue, and I’ve passed your report to the team.

The [unknown] [canceled] This operation was aborted errors are a separate issue that is typical for 1.0.31. In 1.0.34, the SDK started closing unused HTTP/2 connections during idle time so a long-running process doesn’t try to write to a connection that was already closed. The stall now comes through as a retryable NetworkError with code connection_stalled, instead of a plain cancel. More details here: Cursor SDK release notes | Cursor Docs

What you can do now:

  1. Update @cursor/sdk to the latest version.
  2. Wrap agent.send() in your own timeout, for example 60 to 120 seconds. If it fires, restart the worker process instead of just creating a new agent. A new agent in the same process may wait on the same stuck step, and from what we can tell, that’s what happened on the second attempt.

If it happens again on the latest version, send over the agent ID, the time in UTC, and about how long the process had been idle before that send().