@cursor/sdk 1.0.18 Unhandled promise rejection on session auth error crashes host process

Where does the bug appear (feature/product)?

Cursor SDK

Describe the Bug

When using @cursor/sdk (^1.0.18) in a long-running Node.js service, if an Agent
instance goes idle for approximately 30-44 minutes and then agent.send() is called
again, the SDK’s internal gRPC stream processor throws a ConnectError (code 16 /
UNAUTHENTICATED) as an unhandled Promise rejection that crashes the host process.

The error bypasses the SDK’s own convertConnectError() error conversion layer and
never reaches the run.wait() Promise. The caller’s try/catch around run.wait()
is never triggered. The raw ConnectError appears in a parallel internal Promise
chain that the host application has no access to.

This makes it impossible to build a resilient long-running service with the SDK
without relying on process.on('unhandledRejection') as a blunt safety net.

Steps to Reproduce

  1. Create an Agent: const agent = await Agent.create({ apiKey, model, mode: "agent", local: { cwd, store, settingSources: ["project"] } })
  2. Send a message and wait for completion:
    const run = await agent.send("hello", { mcpServers });
    const result = await run.wait(); // succeeds
    
  3. Wait 30-45 minutes without any activity on this agent instance
  4. Send another message on the SAME agent instance:
    try {
      const run2 = await agent.send("follow up", { mcpServers });
      const result2 = await run2.wait();
    } catch (err) {
      // THIS CATCH NEVER FIRES
      console.error("caught:", err);
    }
    
  5. Observed: Node.js process exits with code 1. The catch block is never reached.

Expected Behavior

  • The run.wait() Promise should reject with an AuthenticationError (via the SDK’s convertConnectError() mapping)
  • OR agent.send() should reject with AuthenticationError
  • In either case, the caller’s try/catch should be able to handle the error gracefully
  • The host process should NOT crash

Operating System

MacOS

Version Information

  • @cursor/sdk: 1.0.18 (installed via ^1.0.18)
  • @connectrpc/connect: bundled with SDK (transport layer where error originates)
  • Node.js: 20.12.2

Additional Information

Stack trace of the unhandled rejection:

ConnectError: [unauthenticated] Error
    at errorFromJson (file:///.../node_modules/@connectrpc/connect/dist/esm/protocol-connect/error-json.js:53:19)
    at endStreamFromJson (file:///.../node_modules/@connectrpc/connect/dist/esm/protocol-connect/end-stream.js:64:11)
    at Object.parse (file:///.../node_modules/@connectrpc/connect/dist/esm/protocol-connect/end-stream.js:118:24)
    at file:///.../node_modules/@connectrpc/connect/dist/esm/protocol/async-iterable.js:399:75
    at Generator.next (<anonymous>)
    at resume (file:///.../node_modules/@connectrpc/connect/dist/esm/protocol/async-iterable.js:28:44)
    at fulfill (file:///.../node_modules/@connectrpc/connect/dist/esm/protocol/async-iterable.js:30:31)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

Does this stop you from using Cursor

Sometimes - I can sometimes use Cursor

This is a known issue, and the host-process crash is already fixed.

The fix shipped in @cursor/sdk 1.0.19 (the current latest on npm). You’re on 1.0.18, which predates it, so upgrading should resolve the crash:

npm install @cursor/sdk@latest

One expectation to set: surfacing that underlying error as a typed, catchable error on run.wait() (so your try/catch receives an AuthenticationError instead of the run resolving with a bare status: "error") is a separate improvement we’re still working on. After upgrading, a failed run may still resolve with status: "error" rather than throwing — but it won’t crash the process.

If you still see the process exit after moving to 1.0.19, reply here with the version and stack trace and I’ll dig in further.

Thanks for the update. Would be nice if you could have detailed change logs for your different products so that folks are able to tell what is fixed and when (and not just a /changelog that is more like a blog)