[BUG] Desktop: input-box Stop button kills unrelated background subagents from earlier turns (no warning; Bash background tasks survive; same version previously did not do this)

Status Open
Reported on v2.1.219
Maintainer reply None cached
Activity 4 comments · opened Jul 30, 2026

Environment

  • Claude Code engine 2.1.219, running inside the Claude desktop app 1.24012.9 (entrypoint: claude-desktop)
  • macOS (Darwin 25.5.0), Apple Silicon

Summary

Pressing the Stop button in the chat input box (the one that appears while the assistant is streaming a reply) now also kills running background subagents (spawned via the Task/Agent tool), including agents that were spawned in earlier, already-completed turns and are unrelated to the reply being stopped. There is no warning, no confirmation, and the killed agents cannot be resumed (Agent ... was stopped by the user and won't be resumed).

Meanwhile, background Bash tasks (e.g. a python3 -m http.server, polling loops) survive the same Stop press, and externally-spawned processes are unaffected. So the Stop button currently kills "some but not all" background work, with no visible logic.

What happened (two incidents, 2026-07-30, timestamps EDT)

  1. 08:26 — user pressed Stop mid-stream simply to interject a correction to the reply being written. A file-editing subagent spawned ~1 minute earlier in the same turn was killed (~3 min of work lost).
  2. 10:10 — user pressed Stop mid-stream again to add one sentence. A file-editing subagent spawned at 10:00 in a different, long-finished turn — with a full conversation turn in between — was killed after 9m58s of work. The interrupted reply had nothing to do with that agent.

In both cases the user's intent was only "stop typing, I want to add something". Ten minutes of subagent work were lost as a side effect. (Both agents fortunately followed small-commit discipline poorly enough to leave zero partial changes, but that's luck, not design.)

Inconsistency on the same version

Transcript evidence from the same machine, same engine version 2.1.219, two days earlier (2026-07-28 ~02:59 UTC): the user interrupted a streaming reply while a background subagent (spawned at 02:24 UTC in an earlier turn) was running — that agent survived and completed normally at 03:25 UTC. So on 2.1.219 we have both behaviors observed: interrupt-does-not-kill (07-28) and interrupt-kills (07-30, twice). Either there is a hidden trigger condition, or the kill is nondeterministic. We could not identify the differentiator: same app version (no restart between 07-25 and 07-29 per main.log), same entrypoint, agents in both cases spawned in earlier turns and running quietly in the background.

Expected behavior

The input-box Stop button should stop the streaming reply only — matching the semantics of the stop button on claude.ai web, and matching how this same desktop app behaved on 07-28. Background tasks already have their own per-task stop controls in the "Background tasks" panel; that is the right place for killing them deliberately.

If killing background agents on Stop is intentional, it should at minimum:

  • ask for confirmation or clearly indicate the blast radius ("also stop 2 background tasks?"),
  • be consistent (currently Agent tasks die, Bash tasks survive),
  • and not apply to agents spawned by earlier, already-completed turns.

Impact

Users who interject during streaming (a very common, previously-safe action) silently lose long-running background work. Non-technical users have no way to understand why their tasks show "Stopped".

View original on GitHub ↗

4 Comments

joj303 · 1 month ago

Additional observations from the same user, refining the report:

  • Single press confirmed (not a double-press artifact): one press cuts the streaming reply and the stop button immediately morphs back into the send/return control. Both background-agent kills described above were single presses.
  • The input-box stop control only exists during user-initiated turns. When the assistant is generating output in a turn triggered by a background task notification (reviewing a completed task, dispatching follow-ups), the input box shows no stop button — that streaming output cannot be interrupted from the input box.
  • To be precise about what CAN be stopped: background tasks themselves each have their own stop button in the Background tasks panel, and that works fine — which is exactly our point: a deliberate, per-task kill control already exists in the right place. The input-box Stop therefore has no need to also kill background agents as a side effect of interrupting a reply.

Happy to provide sanitized transcript excerpts (timestamps, task lifecycle events) if useful.

joj303 · 1 month ago

Controlled experiment (same user, reproducing deliberately):

Setup: spawned two identical expendable background subagents, test1 and test2, each writing a heartbeat line to its own file every 10s. User then asked the assistant about test1 only and pressed the input-box Stop while the reply was streaming (before the assistant had even read test1's file).

Result: both agents were killed within the same ~5-second window (test1 last heartbeat 11:19:25, test2 last heartbeat 11:19:29, stop pressed ~11:19:30; neither produced its next scheduled beat).

This rules out any connection to which task the conversation was about — the input-box Stop indiscriminately kills all running Agent-type background tasks, including ones never referenced in the conversation. Reproducible on demand.

joj303 · 1 month ago

Timeline refinement — the boundary is a host reboot + app relaunch, not nondeterminism.

Re-sorting all observations (local EDT):

  • Jul 27 ~23:00 — interrupt pressed, background agent survived (old behavior). App process had been running continuously since Jul 25.
  • Jul 29 ~18:55 — full machine reboot; desktop app relaunched 18:59 (same app version 1.24012.9, same engine version 2.1.219 recorded in transcripts on both sides).
  • Jul 30 08:26, 10:10, and the 11:19 controlled experiment — every interrupt killed background agents (new behavior).

So each era is internally consistent: stop-does-not-kill before the relaunch, stop-kills-everything after it — with identical version strings on both sides. That suggests the behavior change arrived via something a relaunch picks up (hot-updated component, remotely flipped feature flag) rather than a visible version bump. Hopefully that narrows down where to look.

joj303 · 1 month ago

Controlled experiment #2 — rules out any interaction with hooks config.

Since our environment has several UserPromptSubmit hooks configured, we re-ran the two-dummy-agent experiment with the entire hooks.UserPromptSubmit array temporarily disabled (key renamed; verified disabled — no injections, hook script untriggered). Result: pressing the input-box Stop during a streaming reply again killed both background agents within seconds (last heartbeats 11:36:08 / 11:36:10, next beats absent).

So the kill behavior is independent of user hooks entirely. Combined with the timeline in the previous comment, everything still points to the behavior arriving with the app relaunch on Jul 29.