Process death leaves local agent run stuck as running

Where does the bug appear (feature/product)?

Cursor SDK

Describe the Bug

I persist local agents with JsonlLocalAgentStore. When the host process dies mid-run, the agent row stays status=running with an activeRunId, and the run row stays status=running with endedAt=null. After I restart, Agent.resume plus send throws AgentBusyError: Agent already has active run. createFollowUpRun treats any non-terminal stored run as live. There is no API to close an orphaned run without a live Run handle, so I cannot recover except by editing the store.

Steps to Reproduce

I started a local send against JsonlLocalAgentStore, then the process died with no cancel or dispose after a nested agent killed Vite and took the API down. After I brought the process back, Agent.resume of the same agentId plus send threw AgentBusyError. Store evidence: agent-9a9d348c-d325-4a15-b14f-7f9693a1b3cd and agent-d51ef202-e72d-4bad-b8cd-a1582cf0a152 both left status=running, activeRunId set, run endedAt=null. UI cancel returned 409 because the new process had no in-memory Run.

Expected Behavior

After process death, resume should mark the orphaned run cancelled, or let me cancel it on the resumed agent, so the next send proceeds. AgentBusyError should mean a run is actually live.

Version Information

@cursor/sdk 1.0.27, Node v22.22.1, linux 6.12.76, models composer-2.5 and grok-4.6

Hey, thanks for the detailed report. The store evidence and versions make sense.

For now the only workaround is what you already found. Manually move the orphaned run to a terminal state in the store. In JsonlLocalAgentStore, for the affected agent set the run to status=cancelled and set endedAt to a non-null value, then clear activeRunId on the agent row. After that, createFollowUpRun will stop treating the old run as live, and the next send() will work.

About the root issue. AgentBusyError shouldn’t fire when the run isn’t actually live, and there should be a way to close an orphaned run on a resumed agent without a live Run handle. I shared this with the team as a limitation of the current API. I can’t give an ETA yet, but I’ll reply in the thread if there’s an update.

If you can share a minimal repro example like a small script that starts a local send, kills the process, then does resume plus send, it will speed up the investigation.