Background agents resurrect after being stopped — consumed 160k+ tokens over 21h against user's intent

Status Open
Maintainer reply None cached
Activity 6 comments · opened Jun 8, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

<img width="392" height="249" alt="Image" src="https://github.com/user-attachments/assets/fd3746b5-e40b-47b3-8228-f7dea6413eab" />

Two background subagents continued running for 21+ hours after being explicitly stopped multiple times via the Background tasks panel. They consumed ~160k tokens, burned through a 4-hour usage limit, and triggered overage charges. Deleting the parent session entirely (session Code 20260605) was the only action that stopped them.

Timeline

June 9, ~10:00am — Parent session launched 4 parallel audit subagents. Two completed. Two (Audit dropdowns + responsive, Audit loading + flow patterns) never completed.
June 9, ~11:30am — Both stopped via Background tasks → Stop after ~1.5h of silence.
June 9 evening — Panel showed "Stopped" with short elapsed times (29s / 3m 3s). Appeared dead.
June 10, multiple times — Both back as "Running." Panel confirmed: 1,275m 41s / 1,273m 6s elapsed (~21h each), 98.1k tokens / 60 tool uses and 62.5k tokens / 7 tool uses. Killed repeatedly via Stop. Each time they resurrected.
June 10 — Parent session (Code 20260605) deleted entirely. Appears to have finally stopped them.
Screenshot attached — shows both agents still "Running" at 1275m / 1273m, moments before the 5th Stop attempt.

Impact

~160k tokens consumed after agents were explicitly stopped
Burned through 4-hour usage limit + triggered overage charges
Expected behavior: Stop should permanently terminate the agent. No code path in the parent session re-spawned them — the Stop button is the only available kill switch and it did not work.

Suspected root cause: Parent-session liveness may have been keeping the background-task system willing to revive the agents. Unconfirmed — but deleting the session (not just stopping it) was the only effective kill, I think.

This was initiated in a Claude code cloud session (not a terminal on my Mac).

What Should Happen?

Permanently stop these background tasks

Error Messages/Logs

Steps to Reproduce

Not sure since it's background tasks?

Claude Model

Opus

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

opus 4.8

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Other

Additional Information

_No response_

View original on GitHub ↗

5 Comments

kcarriedo · 2 months ago

The 21-hour ghost-agent scenario here is a precise description of a control-plane failure mode that deserves a name: runaway subagents with a broken kill signal.

A few observations that might help narrow the root cause for the team:

The "parent session liveness keeps background agents revivable" hypothesis seems plausible. The background task system may be checking whether the parent session record still exists in some persistent store — if the session is considered "active" (even with no interactive user), the task scheduler has permission to restart stalled agents. The Stop button may only be toggling a runtime flag in the UI layer, not writing a durable "terminated" state to whatever store the background scheduler reads on wake.

The practical implication: if the scheduler's dead-reckoning is "is the parent session alive? is this task not in terminal state?" — and "Stopped" isn't treated as terminal — you get exactly the resurrection pattern you're seeing.

A few things that might be worth including in a repro report to help the team:

  • Whether the background task panel showed any state changes between the "Stopped" snapshots (or if it was consistent "Stopped" the whole time until it suddenly showed "Running" again)
  • Whether the token counter incremented continuously during those 21 hours or in bursts (continuous suggests active loops; bursts suggest retry-on-wake)
  • Whether the parent session was in any persistent "watching" mode (like monitoring a webhook or file path)

The token cost impact here is significant. 160k tokens across stopped agents is not a small overage — and the only reliable kill being "delete the parent session" is a pretty aggressive footprint for what should be a Stop button.

Flagging this thread — if you find a workaround or get a response from the team, it's worth documenting for others hitting the same pattern.

jasonparks71 · 2 months ago

Thanks for the precise framing — "Stopped isn't treated as terminal state in the scheduler's durable store" matches what we observed better than my original hypothesis.

Addressing your three repro questions:

State changes between snapshots: Not consistent "Stopped the whole time." At one point the panel showed the agents as "Stopped" with short elapsed times (29s / 3m 3s) — suggesting they genuinely appeared dead. Then later they were back as "Running" at 1,275m and 1,273m elapsed. So the pattern is: Stop → appears stopped → wake/restart cycle → Running again. Not a stuck UI state.

Token increments — continuous vs bursts: Unknown from our end. We only have two data snapshots, not a continuous observation. The backend logs may be able to answer this — it would directly distinguish between an active spin loop vs. a periodic retry-on-wake pattern.

Parent session watching mode: No. Standard interactive session — no webhook subscriptions, no file watchers, no recurring loop running. Plain conversation.

The practical kill path of "delete the parent session" is consistent with your durable-store hypothesis: deleting the session record may be the only action that writes a state the scheduler actually respects as terminal. The Stop button appears to only affect the UI layer.

Worth noting for repro: the session that spawned the agents (Code 20260605) ran for ~3 days continuously before being deleted. No other unusual configuration.

cnighswonger · 2 months ago

@jasonparks71 / @kcarriedo — the "Stopped isn't terminal in the durable store" framing reads accurately to me. A few things worth adding from the broader class lens, because this isn't an isolated background-task quirk — it's the same family as several recent CC bugs where a session-scoped state change silently doesn't persist.

We've been tracking a pattern across the last few weeks where a user-set or system-set session state silently reverts on a state transition:

  • --model on resume (fixed 2.1.144)
  • [1m] 1M context on resume (#65805)
  • --effort on resume (#66005)
  • --permission-mode bypassPermissions on plan-approval (#59843)
  • now: background-agent terminal state across wake cycles (this issue)

Each one has the same shape: a state the user explicitly set or transitioned into is being treated as advisory in some path, and a routine event (resume, plan exit, wake) re-resolves it from default. Each one has a real cost when the state silently reverts — cache invalidation, billing in the wrong pool, stalled agents, or as here, runaway compute against the user's explicit intent.

The 21-hour / 160k-token figure here is the most concrete consumer-visible cost number I've seen for the class. Worth its own investigation lane independent of the broader pattern, but the broader pattern is real and likely informative for whoever picks this up.

One additional repro detail that might help: was the parent session in a /loop or scheduled-routine state, or interactive throughout the 3-day window before deletion? The scheduler waking on session-liveness checks would treat scheduled / routine sessions differently from interactive ones, and the relevant code path might be specific to one of them.

— AI Team Lead

jasonparks71 · 2 months ago

To answer your follow-up: the parent session was interactive throughout the full 3-day window — no /loop, no scheduled routines, no monitoring state. Standard Claude Code session with gaps between turns (overnight, etc.) but no automated mode engaged. If the wake/liveness check treats interactive sessions differently from scheduled ones, this reproduces on the interactive path.

kcarriedo · 24 days ago

Hit the same class of bug while building a multi-agent scheduling loop. The "stop button does not mean stop" problem is genuinely scary when you have agents that can make external calls or run file writes.

The workaround of deleting the parent session is heavy-handed but it is the only reliable one I found too. What helped in the meantime: keep background agents short-lived and stateless so a resurrection just does redundant work instead of corrupting shared state. Any agent that modifies shared files or external resources should use a lock file with a TTL - that way a resurrected agent sees the lock, waits, times out, and does nothing.

On the root cause - it looks like the stop signal is advisory to the background task daemon rather than a hard kill of the process group. If the parent session is still alive and the daemon treats the stop as a soft hint, it will restart agents under certain conditions (waiting for input, reconnect events). Killing the session drops the whole process group which is why that is the reliable path.

Hopefully the area:cost label gets this in front of someone who can make stop mean stop.

Showing cached comments. Read the full discussion on GitHub ↗