Desktop (Code tab): withdrawing/editing a message kills ALL background tasks, including ones launched before the rewind point (terminal rewind keeps them)

Status Open
Reported on v2.1.295
Maintainer reply None cached
Activity 0 comments · opened Oct 10, 2026

Environment

  • Claude desktop app 2.31226.1 (macOS), Code tab, local session
  • Bundled Claude Code runtime 2.1.295. The terminal control was also 2.1.295. (2.1.296 landed on disk during testing; I haven't tested it.)
  • macOS 27.2 (26B5101f), Apple Silicon

Summary

#78396 was closed as fixed: on current versions a terminal rewind (Esc Esc → Restore conversation) leaves background shells and background subagents running. In the desktop app it is still broken. Withdrawing or editing a message tears down the whole Claude Code process. Every background task gets SIGKILLed, including tasks whose spawning tool calls are before the rewind point and so stay in the surviving conversation. There is no warning first. The model isn't told until the user's next message. The killed subagent can't be resumed afterwards (SendMessage → "No transcript found").

#78396 is locked, so I'm filing this as a new issue.

Steps to reproduce (desktop)

  1. Open a new Code session in an empty scratch folder.
  2. Message 1: ask Claude to start a background Bash sleep 600 and end its turn.
  3. Message 2: ask Claude to start a background Bash sleep 900 and a background subagent (Agent tool, run_in_background, no worktree isolation) that runs ping -c 60 127.0.0.1 five times as separate foreground Bash calls, then end its turn. (Use ping, because standalone sleep in a subagent is blocked by the harness.)
  4. Message 3: hello again.
  5. Confirm the three tasks are running (pgrep -lf 'sleep (600|900)$|ping -c 60').
  6. Withdraw/edit message 3. All three tasks were launched in messages 1–2, before the rewind point.
  7. Send any new message.

Expected

The same as the terminal (#78396, and the maintainer's test on 2.1.233): tasks launched before the rewind point keep running and report back normally. Only tasks spawned after the rewind point may be stopped.

Actual

  • Right after the withdraw, the Claude Code process and all three task processes are gone. The subagent's ping tool result is Exit code 137 (SIGKILL), and both shell outputs end in [killed].
  • The UI shows a grey "3 background tasks stopped" line under the last turn. It looks informational, not like an error. No confirmation dialog appeared before the withdraw.
  • Nothing wakes the model. No Claude Code process runs for this session until the user sends the next message.
  • On the next message, a new process starts as a fork under a new session ID. Two task-notifications are injected in front of the user's message:

> Background agent "Run ping 60s five times" didn't finish before the previous session ended … It was running when the previous Claude Code process exited and did not complete. Its in-process state was lost.

> 2 background shell command tasks didn't finish before the previous session ended.

The UI line changes to "1 background task failed, 2 stopped". So the same agent is reported as "stopped" first and "failed" later.

  • SendMessage to the killed agent from the new session fails:

> No transcript found for agent ID: <agent-id>. If you read this id in a message from another Claude Code process … it never ran in this session …

The transcript is still on disk, but under the pre-rewind session's folder (see below).

Terminal control (same machine, same version, same steps)

claude in a terminal, the same two background tasks, then a third message, then Esc Esc → pick that message → "Restore conversation":

  • After the rewind, the rewound turn is gone from the view. The footer still shows 1 shell and the running general-purpose agent ("Waiting for 1 background agent to finish").
  • sleep 900 stayed alive under the same claude PID. The subagent's in-flight ping completed normally, and the subagent went on to its next ping calls.
  • The rewind really branched the conversation: the next message (status?) has the same parentUuid as the rewound message in the transcript. Claude then reported both tasks still running, with no "didn't finish" notifications.

Evidence

Desktop log (~/Library/Logs/Claude/main.log):

[info] LocalSessions.rewindV2: sessionId=<desktop-session-id> target=<target-uuid>
[info] Stopping session <desktop-session-id>
[info] [CCD] Session <desktop-session-id> torn down with 4 live task(s) — settling as stopped (exited)
[info] [Rewind] resumeSessionAt=<resume-at-uuid> + forkSession for session <desktop-session-id>

(The log says 4 live tasks. 3 task processes were alive at the time. I haven't worked out what the 4th entry is; it may be the subagent's own in-flight Bash call.)

Processes before the withdraw, all children of the session's Claude Code process:

78062  sleep 600            (bg Bash, message 1)
87098  sleep 900            (bg Bash, message 2)
87255  ping -c 60 127.0.0.1 (subagent <agent-id>, message 2)

After the withdraw: none of them, and no Claude Code process for the session.

The process spawned on the next message:

claude … --resume=<old-session-id> --fork-session --resume-session-at=<resume-at-uuid>

→ new CLI session <fork-session-id>.

Transcript folders (~/.claude/projects/<project>/):

<old-session-id>/subagents/agent-<agent-id>.jsonl   # killed agent's transcript, still here
<fork-session-id>/                                         # fork: only custom-title.json, no subagents/

The same thing happened in a real session: a worktree-isolated background agent was killed by a withdraw (torn down with 2 live task(s)). Its uncommitted work had to be recovered by hand.

Where it seems to come from (desktop bundle 2.31226.1, app.asar → .vite/build/; minified names are version-specific)

  • rewindSessionV2 calls stopSession(sessionId, true), then teardownWarmIfIdle(session, "rewind"), then sets session.pendingRewindTo = <target>. No live background tasks are checked before the teardown.
  • On teardown, settleBackgroundTasksForDeadCli logs torn down with N live task(s) — settling as stopped, pushes a task_notification with status stopped / summary "Ended when the Claude Code process exited" into the UI message buffer, and records desktop_ccd_background_task_killed_by_teardown. That notification goes to the renderer only. No Claude Code process is running to receive it.
  • The next spawn sets resume = cliSessionId, resumeSessionAt = pendingRewindTo, forkSession = true, which becomes --fork-session --resume-session-at.
  • The desktop's own user-initiated Fork (LocalSessionManager.forkSession) does copy referenced subagent transcripts into the new session (discoverReferencedAgentIds → copies agent-<id>.jsonl, logging "could not copy subagent transcript agent-… into the fork" on failure). The rewind path relies on the CLI's --fork-session instead, and that leaves subagents/ behind. This explains the "No transcript found" (same symptom as #79764).

Suggested fix

  1. Don't kill pre-rewind tasks. Rewind in-process, as the terminal does: keep the Claude Code process and branch the conversation. Or, if a restart can't be avoided, stop only the tasks spawned after the rewind point.
  2. If a teardown can't be avoided:
  • Warn before rewinding while background tasks are running ("N background tasks will be stopped"), with an option to cancel.
  • Carry the subagent transcripts into the fork (reuse the copy step that user-Fork already does), so SendMessage can resume the agent.
  • Label the kill clearly. "stopped" is shown for something the user never asked to stop. Use one status consistently: "stopped", then "failed" later, is confusing.
  • Wake the session, or at least show something clearer than a grey line, so the user and the model learn about it when it happens rather than on the next message.

Related

  • #78396: Rewind/edit kills ALL background tasks (terminal; closed as fixed in 2.1.196, locked)
  • #79764: "No transcript found for agent ID" after a fork; transcript sits in the pre-fork session dir
  • #63023: Background agents silently die on session pause/resume, no completion notification
  • #75438: Background task completion notifications lost after CLI process restart
  • #100122: Desktop rewind/edit resumes in the launch folder instead of the worktree
  • #95211, #78151: other paths that silently kill background agents (Stop button, interrupt)

View original on GitHub ↗