claude-code - 💡(How to fix) Fix Scheduled tasks and background sub-agents leak processes/UI state without cleanup [1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#54626Fetched 2026-04-30 06:40:28
View on GitHub
Comments
1
Participants
2
Timeline
7
Reactions
0
Timeline (top)
labeled ×6commented ×1

A scheduled task or background sub-agent that completes its work successfully often does not exit cleanly. The harness lacks per-tool wall-clock timeouts, never SIGKILLs hung children, and leaves stale UI state with no way to clear it. Over a week these leaks accumulate to ~1.5 GB of zombied RAM and a Tasks panel cluttered with phantom "Running" entries.


Error Message

  1. Per-tool wall-clock budget enforced by harness. If a single tool call doesn't return within N seconds (configurable, default ~120s), the harness should mark the call failed and feed an error back to the agent rather than letting the child sit forever on stdin. This alone would fix the silent-hang case.

Root Cause

A scheduled task or background sub-agent that completes its work successfully often does not exit cleanly. The harness lacks per-tool wall-clock timeouts, never SIGKILLs hung children, and leaves stale UI state with no way to clear it. Over a week these leaks accumulate to ~1.5 GB of zombied RAM and a Tasks panel cluttered with phantom "Running" entries.


RAW_BUFFERClick to expand / collapse

Environment

  • Claude Code: 2.1.119
  • OS: Windows 11 Pro (10.0.26200) — observed on Windows; lifecycle/cleanup logic likely platform-agnostic
  • Shell: Git Bash + PowerShell

Summary

A scheduled task or background sub-agent that completes its work successfully often does not exit cleanly. The harness lacks per-tool wall-clock timeouts, never SIGKILLs hung children, and leaves stale UI state with no way to clear it. Over a week these leaks accumulate to ~1.5 GB of zombied RAM and a Tasks panel cluttered with phantom "Running" entries.


Symptom 1 — Scheduled-task processes zombify after completing their work

A daily scheduled task (scheduled-tasks MCP, fires at 08:08) writes its output file successfully, but the underlying claude-code\2.1.119\claude.exe --output-format stream-json process never exits. After 4 days I had 4 zombied processes from the same daily task, each holding 200–600 MB resident.

A separate failure mode: one day the scheduled task hung mid-run (an MCP tool call apparently never returned). It produced no output at all and ran for 24+ hours. There is no per-tool wall-clock timeout to catch this — the child sits forever waiting on stdin from a parent harness that has long since lost interest.

Reproducer: create a scheduled task that calls a moderate set of MCP tools (the more servers in the chain, the higher the chance one stalls). After ~1 week, list claude.exe processes — expect to see one extra zombie per successful run, plus any hung mid-run.


Symptom 2 — Background bash tasks remain "Running" in the Tasks panel after their OS processes exit

I spawned a background sub-agent via the Agent tool (run_in_background: true) for a 10-minute pure-local audit. The sub-agent itself completed cleanly and emitted its <status>completed</status> notification. But during execution it had spawned several nested background bash commands (e.g. until [ -f flag ]; do sleep N; done polling loops). After the parent agent completed:

  • ✅ All bash.exe / sh.exe OS processes had exited (verified via Get-CimInstance Win32_Process)
  • ❌ Five entries remained in the Tasks panel labeled "Running" indefinitely

Symptom 3 — No working path to clear the phantom entries

PathResult
Click X on the entry in the Tasks panelNo effect — entries persist
Call TaskStop with task ID derived from ~/AppData/Local/Temp/claude/<session>/tasks/<id>.outputReturns No task found with ID: <id>
Restart Claude CodeWorks (clears panel)

Whatever ID format the panel uses internally is not reachable from either the UI's own dismiss control or from TaskStop. Restart is the only escape.


Suggested fixes (in priority order)

  1. Per-tool wall-clock budget enforced by harness. If a single tool call doesn't return within N seconds (configurable, default ~120s), the harness should mark the call failed and feed an error back to the agent rather than letting the child sit forever on stdin. This alone would fix the silent-hang case.

  2. Hard exit-after-completion for scheduled tasks. When a --output-format stream-json --resume <task-session-id> child emits its terminal turn message and stdin closes, the harness should SIGKILL after a short grace period instead of leaving the child alive.

  3. Tasks panel state should track underlying process exit. When a background bash task's OS process terminates, its panel entry should flip to "Completed" / "Failed" within seconds, not stay "Running" forever.

  4. Either fix the X button or align TaskStop's ID lookup with the panel's IDs. Right now the user has no in-session escape from a stuck panel entry.


Evidence available on request: PowerShell Get-CimInstance output of zombied processes by age/RAM, full command lines showing the headless flags (--output-format stream-json --verbose --input-format stream-json --model default --permission-prompt-tool stdio --allowedTools mcp__computer-use,...), the smoke-test agent's transcript showing clean completion, and the temp-dir task ID file listing whose IDs TaskStop rejects.

extent analysis

TL;DR

Implementing a per-tool wall-clock timeout and ensuring clean exit of scheduled tasks and background sub-agents can help resolve the issue of zombied processes and phantom "Running" entries in the Tasks panel.

Guidance

  • Implement a configurable per-tool wall-clock timeout to prevent tools from hanging indefinitely, as suggested in the issue.
  • Modify the harness to enforce a hard exit-after-completion for scheduled tasks, using a short grace period before SIGKILLing the child process.
  • Update the Tasks panel to track the underlying process exit and update the entry status to "Completed" or "Failed" accordingly.
  • Align the TaskStop ID lookup with the panel's IDs or fix the X button to allow users to clear stuck panel entries.

Example

No code snippet is provided as the issue does not contain specific code examples, but the suggested fixes can be implemented in the Claude Code harness and Tasks panel logic.

Notes

The issue is specific to the Claude Code environment and may require modifications to the underlying codebase. The suggested fixes are based on the provided information and may need to be adapted to the actual implementation.

Recommendation

Apply the suggested fixes, starting with implementing a per-tool wall-clock timeout, to address the root causes of the issue and prevent zombied processes and phantom "Running" entries.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix Scheduled tasks and background sub-agents leak processes/UI state without cleanup [1 comments, 2 participants]