Where does the bug appear (feature/product)?
Cursor SDK
Describe the Bug
When a local SDKAgent instance created via Agent.create() sits idle for approximately 15 minutes, the next agent.send() call fails with ERROR_NOT_LOGGED_IN (gRPC status code 16 / UNAUTHENTICATED). The error is surfaced as an AuthenticationError with isRetryable: false.
This is a misclassification. The API key is valid – creating a fresh agent via Agent.create() or Agent.resume() with the same key succeeds immediately. The underlying issue is a stale gRPC connection, which should surface as a NetworkError with isRetryable: true.
Because the error is classified as AuthenticationError, the SDK’s built-in enableAgentRetries transport retry (default: true) does not handle it. Consumers must implement their own retry logic to work around what should be an SDK-managed transport recovery.
Steps to Reproduce
- Create a local agent with a valid API key:
const store = new JsonlLocalAgentStore("./agent-store"); const agent = await Agent.create({ apiKey: process.env.CURSOR_API_KEY, model: { id: "claude-sonnet-4-6" }, mode: "agent", local: { cwd: "/path/to/repo", store }, }); - Send a message successfully:
const run = await agent.send("Hello"); await run.wait(); - Wait ~15 minutes with no activity on the agent
- Send another message:
const run2 = await agent.send("Follow-up"); await run2.wait(); - Observe:
run2.wait()resolves with{ status: "error" }containingERROR_NOT_LOGGED_IN - Alternatively, the SDK throws
AuthenticationErrorwith message[unauthenticated] Error
Expected Behavior
- The SDK should either transparently reconnect (since
enableAgentRetriesis true and this is a transport-level issue), or - Surface the error as
NetworkErrorwithisRetryable: trueso consumer retry logic can handle it correctly - The error should NOT be
AuthenticationErrorsince the API key is valid
Operating System
MacOS
Version Information
@cursor/sdk: 1.0.19- Node.js: v22.x
- OS: macOS (darwin 25.5.0) – also expected on Linux containers
- Agent type: local (not cloud)
- Store:
JsonlLocalAgentStore enableAgentRetries: default (true)
Additional Information
- The gRPC status code 16 (UNAUTHENTICATED) from the Cursor backend is the source of the misclassification. The server-side connection cleanup triggers this code rather than UNAVAILABLE (14) or DEADLINE_EXCEEDED (4).
Agent.resume(agentId)with the same API key succeeds immediately after the failure, confirming the key is valid and only the connection is stale.- In a long-running server process (e.g., Fastify service acting as an AI agent pod), agents frequently go idle between user interactions. This pattern reliably triggers the bug after ~15 minutes.
- Workaround: catch the error, evict the cached agent, call
Agent.resume(agentId)to get a fresh connection with preserved conversation state, and retry the send.
Does this stop you from using Cursor
Sometimes - I can sometimes use Cursor