Error resuming chat after long background Shell finishes (Request ID 57b6008d-8c6b-4cce-86ac-59caf380ce4c)

Where does the bug appear (feature/product)?

Cursor IDE

Describe the Bug

Error resuming chat after a long background Shell finishes. Toast: “A background task finished, but the chat couldn’t resume. Try again in a moment.” The Shell/watch itself succeeds (exit 0); only parent-chat reattach fails. Started happening frequently once we use long CI watches (~15–20 min) with notify_on_output.

Steps to Reproduce

  1. In Agent chat, start a long background Shell (block_until_ms: 0) that runs 10–20+ minutes (e.g. gh pr checks --watch / CI babysit watch).
  2. Arm notify_on_output so Cursor wakes when the Shell prints a completion sentinel.
  3. Leave the chat idle while it runs.
  4. When the Shell finishes, Cursor shows “Error resuming chat” instead of continuing the agent turn.
  5. Clicking Resume or sending a new message works; work was not lost.

Expected Behavior

When the background Shell completes, the parent Agent chat should resume automatically on the wake notification and continue the turn (same as short background jobs).

Screenshots / Screen Recordings

Operating System

MacOS

Version Information

Cursor IDE 3.12.17 (arm64)

For AI issues: which model did you use?

Grok 4.5 (parent Agent session). Background work was Shell (CI watch), not a model subagent.

For AI issues: add Request ID with privacy disabled

57b6008d-8c6b-4cce-86ac-59caf380ce4c

Additional Information

Not a project/CI failure — GitHub checks and the watch complete correctly. Correlates with heavy use of long background Shell + notify wakes for merge-queue babysitting. Related to other “Failed to resume after background task completed” reports; our toast is the generic reattach failure (no “model name is not valid” message).

Does this stop you from using Cursor

Sometimes - I can sometimes use Cursor

Hey there!
This is a known rough edge we’ve seen reported before. When a background task finishes after the chat has been sitting idle for a while, the automatic “wake” that should resume your turn can hit a transient hiccup, and right now that surfaces as the “Error resuming chat” toast instead of quietly retrying. Your work is saved - the turn just needs a nudge to pick back up.

To recover when you see it:

  1. Click Resume on the toast, or send any new message in the same chat - either one re-delivers the completion and continues the turn. If Resume doesn’t seem to respond on the first click, sending a message will reliably resume it.
  2. For very long idle stretches, a fresh chat per task tends to make the reattach more reliable.

I’ve flagged your report (with the request ID) to the team so it’s tracked alongside the other reports of this behavior. Since the work itself isn’t lost it shouldn’t block you, but if you ever see it actually drop the completed work, reply here - that’d be a different issue worth digging into.

We hit the same “Error resuming chat” toast and ran a small controlled experiment that narrows down the mechanism. Sharing data in case it helps the team, since it suggests this is more than a transient wake hiccup.

Environment: Cursor 3.14.27 (arm64), macOS 26.5.1, Apple M4 Pro Mac mini (mains-powered, no sleep), privacy disabled.

Protocol: fresh Agent chats each start one background Shell (block_until_ms: 0) running “sleep 1080 && echo SENTINEL” (or sleep 300 in later trials), the agent ends its turn immediately, and the chat is left completely idle. Two variants: with notify_on_output armed on the sentinel, and without it (standard completion notification only). Outcomes were read from the terminal state files on disk plus the UI.

Results — 0 of 4 trials resumed:

- Trial 1 (with notify_on_output): background shell was killed (status “aborted”, exit_code “unknown”) 77 seconds after the turn ended. Toast appeared. Request ID: 1d60bbdb-4e5e-4e49-ba5f-8e315b558429

- Trial 2 (without notify_on_output): shell killed the same way at 94 seconds. Toast appeared. Request ID: fe751c73-b624-4f49-8c4d-3fe49b3c2c3d

- Trial 3 (with notify_on_output): shell killed at 102 seconds. SILENT failure — no toast, no resume within 15 minutes.

- Trial 4 (without notify_on_output): shell SURVIVED, ran the full 300 seconds, exit 0, sentinel printed. Still SILENT — the UI shows “Finished …”, but the agent never resumed and no toast appeared within 14 minutes.

Both toasts carried the same client-side stack (via Copy ID):

```

ConnectError: [deadline_exceeded] Agent Execution Timed Out

at gvp (workbench.glass.main.js:9176:38322)

at Voi.waitForProviderRegistration (workbench.glass.main.js:9176:43755)

at async Jgl.\_waitForPushRequestContextProviderRegistration (workbench.glass.main.js:18950:4327)

at async aNe (workbench.glass.main.js:8489:11978)

at async Object.prepare (workbench.glass.main.js:18950:21313)

at async Jgl.\_runWakeupAction (workbench.glass.main.js:18950:18418)

at async Jgl.\_maybeDispatchBackgroundCompletions (workbench.glass.main.js:18950:23826)

at async Jgl.runIdleHooks (workbench.glass.main.js:18950:30311)

```

Three observations that may help debugging:

1. The background job itself usually dies, not just the wake. In 3 of 4 trials the tracked shell was reaped about 80-100 seconds after the owning turn ended (terminal file shows status “aborted”, exit_code “unknown”), long before the command would have finished. In the original report the watched work survived because it ran remotely on CI — locally the watcher process appears to be killed. So “work is saved” holds only for remote work.

2. notify_on_output is not the discriminator. Both variants fail identically.

3. Even a fully successful completion doesn’t resume the chat. Trial 4’s shell ran to completion (exit 0) and the UI shows “Finished …”, but the agent turn never continued and no toast appeared — a silent stall, which is worse than the toast because there is no signal at all.

For anyone needing a workaround until this is fixed: don’t let an agent turn end while a tracked background shell is running. For jobs that must outlive the turn, detach into a new session and read a log file on the next message. Note that plain “nohup … & disown” is also killed at tool-call boundaries in this environment, and setsid doesn’t exist on macOS, so we use:

```

python3 -c “import subprocess,sys; p=subprocess.Popen([‘bash’,‘-c’,sys.argv[1]], stdout=open(sys.argv[2],‘w’), stderr=subprocess.STDOUT, stdin=subprocess.DEVNULL, start_new_session=True); print(p.pid)” ‘’ /tmp/job.log

```

This pattern (plus polling in slices of 3 minutes or less when staying in the turn) went 2 for 2 in the same test session, including one 27-minute turn.

Happy to run more trials or provide the terminal state files if useful.

Hey @Danil_Nezhdanov,

Confirming a few things: both the toast and the silent case (task finishes, UI shows “Finished”, but the turn never resumes) are consistent with this issue and aren’t anything you misconfigured. And you’re right on “work is saved”: that only holds for work outside the shell (remote CI, or output already written to a file). A local background process may not survive once the owning turn ends.

Your detached-process pattern is the right workaround for anything that needs to outlive the turn: run it fully detached, write to a log file, and read that log on the next message.

We’re tracking this and I’ll post back when there’s an update. If the fully-silent case is easy to reproduce, the terminal state files for one run would help, but no pressure.