Background tasks panel: stopped tasks reappear as Running after session switch / refresh

Status Fixed / completed
Reported on v2.1.142
Maintainer reply ✓ Yes — bogini
Activity 11 comments · opened May 15, 2026 · closed May 27, 2026
💡 Likely answer: A maintainer (bogini, collaborator) responded on this thread — see the highlighted reply below.

Summary

In the Claude Code app's Background tasks side panel, clicking Stop on a Running task visibly moves it to the Completed section with status "Stopped" — but the change does not persist. After leaving and returning to the conversation (session switch, app refresh, or closing/reopening the panel), every task that was previously stopped reappears in the Running section with status "Running", even though no process is actually alive.

Net effect: dead background-task slots accumulate in the UI and can't be cleared. The list grows monotonically across the lifetime of a conversation and survives refresh/restart.

Environment

  • macOS: 26.3 (build 25D125), Apple silicon
  • Claude (desktop app): 1.7196.0
  • Claude Code CLI: 2.1.142 (used as a tool; the UI in question is in the desktop app)
  • Model in session: Opus 4.7 · Max

Reproduction

Trigger condition (how the dead-but-Running slots get created in the first place):

  1. In a Claude Code session, have the assistant call the Task tool to spawn a sub-agent.
  2. Have that sub-agent call Bash with run_in_background: true several times.
  3. Let the sub-agent finish and return.

Result of the trigger: the sub-agent's run_in_background Bash slots appear in the Background tasks panel as Running, indefinitely. ps on the host confirms the underlying processes are gone — no live PIDs. There appears to be no first-class way (no KillBash-equivalent surfaced to the orchestrator) to clear these slots programmatically, so the only path is the panel's Stop button.

The staleness bug (what this report is about):

  1. Open the Background tasks panel. Observe the dead tasks listed under Running.
  2. Click Stop on each dead task one by one. The panel updates correctly: each task moves to Completed with status "Stopped", and the bottom-bar "N shells running" counter decreases as expected.
  3. Click any other conversation in the left sidebar (or refresh the app, or close+reopen the panel — any of these reproduces it), then return to the original conversation.
  4. Open the Background tasks panel again.

Expected: the previously-stopped tasks remain under Completed with status "Stopped". Running shows only the tasks that are genuinely alive.

Actual: every task that was stopped in step 5 is back under Running with status "Running". The Completed section forgets they were ever stopped. The bottom-bar counter shows the full revived count.

Frequency

I've observed this multiple times over the past several days. Confirmed reproducible in the screen recording I'll attach as a comment.

Workaround

None that persists. Clicking Stop again works for the current view but the same tasks return on the next session switch / refresh.

Why it matters

  • The Background tasks panel becomes unreliable as a status signal — you have to manually re-verify with ps whether anything in Running is actually alive.
  • The "N shells running" counter at the bottom of the conversation is similarly misleading: it shows the stale-revived count, not the real count.
  • Combined with the upstream issue (sub-agent run_in_background slots are not reaped when the sub-agent finishes), a single session can accumulate an unbounded number of phantom Running slots that survive every UI refresh, with no in-product way to clear them.

Hypothesis (where to look)

The Stop click handler appears to write to a transient in-memory state, while the panel's render on session open reads from a persisted source (per-session state on disk / server) that still records those slots as Running. Two likely shapes:

  1. The Stop action is not persisted at all — only the local view state is updated. On re-render the panel rehydrates from the unmodified persisted record.
  2. The Stop action is persisted, but to a layer that the re-render path does not consult, so the persisted "stopped" status is masked by a stale "running" record from another layer (e.g. the sub-agent's task ledger).

Either way, the persistence layer that backs the panel on open is the place to look.

Screen recording (what it captures)

27.86 s, 4096×2382 @ 120 fps. Sequence:

  • t ≈ 0–11 s: I click Stop on each dead Running task; the panel correctly migrates each one to Completed/Stopped; bottom-bar counter "N shells running" drops correctly (from 8 → 6 → … → 2).
  • t ≈ 11–17 s: The panel shows only the 2 genuinely-running tasks (two subscribe-pr-mergeable.sh Monitors) in Running; I close the Background tasks panel.
  • t ≈ 17–21 s: I click away to another conversation in the sidebar, then back to the original.
  • t ≈ 21–27 s: I reopen the Background tasks panel — all 8 tasks are back under Running, including every one stopped in the first 11 seconds.

I'll attach the recording + a screenshot in a follow-up comment (file upload).

View original on GitHub ↗

10 Comments

github-actions[bot] · 3 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/58662
  2. https://github.com/anthropics/claude-code/issues/48312
  3. https://github.com/anthropics/claude-code/issues/58457

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

venpopov · 3 months ago

<img width="2244" height="1305" alt="Image" src="https://github.com/user-attachments/assets/628abacc-c98f-4971-9f91-7a0c3c727be5" />
https://github.com/user-attachments/assets/e5d316ce-f305-4476-8c36-0896a43d54a2

mosquss · 3 months ago

The funny thing is that I created an issue on this topic, but it was closed to me lol

mosquss · 3 months ago

the problem has been relevant since the very beginning of beta testing of the interface

mosquss · 3 months ago

experimental interface, it is very laggy

venpopov · 3 months ago

The OP report was generated by local claude code. Not sure if it captured all the nuance. While it talks about the desktop app, the sessions where the problem occurs are cloud sessions, and the problem is the same in the Claude Code web app. Just as additional context.

mosquss · 3 months ago

Moreover, in the web version, after an error (not always, and I can't be sure exactly how, but for me it happened when I sent via clipboard "ctrl + v" - a screenshot without text): "API Error
API Error: 400 messages.141.content.2.text: cache_control cannot be set for empty text blocks" literally the whole session breaks, and after any of your requests the response is "API Error
API Error: 400 messages: text content blocks must be non-empty"

venpopov · 3 months ago

This is now getting much worse and is affecting every session in the last few hours - it was intermittent in the previous days.

bogini collaborator · 3 months ago

Fixed — stopped tasks no longer reappear as running after session switch. Please reopen if you still see this on a current version.

nolanlove · 2 months ago

Still reproduces on Claude Code 2.1.160 — ghost "Running" rows accumulate during a session.

Per the closing note ("reopen if you still see this on a current version"), flagging that a variant of this is still present on a current build.

Repro:

  1. Start a persistent background task running a long-lived loop, e.g. while true; do date; sleep 30; done.
  2. Over a long session with idle periods, let the harness reap the task (or stop it), then start a fresh one. Repeat a few times across the session.
  3. Observed: each reaped task stays in the Running section with a climbing timer even though no process is alive. Confirmed dead three independent ways — ps shows no matching process; the in-session task tooling reports no such task (TaskStop <id> → "No task found"); yet the panel still renders it as Running. The rows accumulate monotonically; a single recurring task reached 4 simultaneous fake-"Running" entries, one with a ~1058m timer.

Partially improved vs. the original report: a full app restart now does move these to Finished / Stopped, so the restart-persistence fix appears to hold. What's still broken is the live, in-session accumulation — a killed persistent task is never moved out of "Running" until a restart, and there's no in-session way to clear a falsely-"Running" row.

Environment: Claude Code 2.1.160 · Claude Desktop · macOS (Apple silicon).

Showing cached comments. Read the full discussion on GitHub ↗