anthropics / anthropics/claude-code
Scheduled-task session processes still leak on 2.1.237 — and each orphan spins ~10% of a core indefinitely (follow-up to #54626)
- Lingua principale
- Python
- Stelle
- 145k
- Fork
- 23.1k
- Metriche di merge delle PR
- Metriche PR in attesa
Descrizione
Follow-up to #54626 (closed 2026-06-16 as "will be fixed in the next release", locked 2026-08-19 with a note to file a new issue). Still reproducing two months and ~90 patch versions later, and with a symptom that thread never captured: **the orphans are not idle — each one spins a core at ~10% for ever.**
## Environment
- Claude Code: **2.1.237** (bundled)
- Claude Desktop: **1.34493.1**
- macOS **26.5.2** (25F84), iMac21,1, 16 GB RAM
- 9 scheduled tasks configured via the `scheduled-tasks` MCP
## Summary
Every session the desktop app spawns — including every scheduled-task run — leaves its `claude` process resident after the run completes. The app reports the session as not running, the transcript stops being written, and the process stays alive indefinitely, burning CPU in what looks like a spin loop rather than blocking on stdin.
After three days without a restart I had **24 orphaned session processes** consuming **~2.7 GB RSS and ~234% CPU** (2.3 cores) continuously, on a machine that was otherwise idle.
## Evidence 1 — the orphans are scheduled-task runs, identifiable by start time
Process start times cluster on the exact scheduled trigger times across consecutive days, with a consistent ~3-second daily drift:
| PID | Started | Task cadence |
|---|---|---|
| 38706 | Sat Aug 22 **05:04:42** | daily task A |
| 34638 | Sun Aug 23 **05:04:45** | daily task A |
| 33718 | Mon Aug 24 **05:04:48** | daily task A |
| 90184 | Sat Aug 22 **07:07:25** | daily task B |
| 88616 | Sun Aug 23 **07:07:28** | daily task B |
| 10907 | Mon Aug 24 **07:07:31** | daily task B |
One process per fire, none reaped. Oldest survivor at the time of capture: Fri Aug 21 19:50:10 — just over 3 days.
Each is paired 1:1 with a `disclaimer` helper, matching the fingerprint reported in #54626:
```
4310 1 /Applications/Claude.app/Contents/MacOS/Claude
33717 4310 /Applications/Claude.app/Contents/Helpers/disclaimer -- .../claude
33718 33717 ~/Library/Application Support/Claude/claude-code/2.1.237/claude.app/Contents/MacOS/claude --output-format stream-json ...
```
## Evidence 2 — each orphan spins a core (new; #54626 only covered RAM)
Sampling accumulated CPU time across a 6-second wall window, every one of the 24 processes advanced its CPU clock:
```
pid cputime(t0) cputime(t0+6s) delta
6940 95:20.69 95:21.34 0.65s
81234 105:47.34 105:47.92 0.58s
60953 22:28.78 22:29.21 0.43s
... (all 24 processes advanced 0.43–0.65s)
```
Sum of deltas: **14.06 CPU-seconds per 6 wall-seconds ≈ 234% of one core**, sustained, with zero sessions running work.
The lifetime figures make the waste concrete: PID 81234 had burned **105 minutes of CPU** while alive 2 days 17 hours, having done nothing since its scheduled run finished on day one. This is not a process parked on a blocking read — something is looping.
On a laptop this is a battery and thermal issue, not just a memory one.
## Evidence 3 — the app agrees the sessions are finished
- `list_sessions` reported `isRunning: false` for **all** of them.
- No transcript in `~/.claude/projects/` had been written for over an hour, except the one session I was actively using.
So nothing in the harness believes work is in flight; the processes are simply never asked to exit.
## Evidence 4 — killing them is non-destructive, which suggests the fix is cheap
`kill` on all 24 freed 2.7 GB and 2.3 cores with no data loss whatsoever. The transcript is the durable state: when a killed session is reopened, the app relaunches it with `--resume=` and the conversation continues intact. I verified this on a session killed an hour earlier — it came back with full history.
If the process can be terminated at any point without consequence, then exiting it when the scheduled run completes should be safe.
## Reproduction
1. Configure a scheduled task via the `scheduled-tasks` MCP on any daily cadence.
2. Leave the desktop app running for several days without restarting it.
3. `pgrep -x claude | wc -l` — expect one additional process per fire, none reaped.
4. Sample CPU: `ps -o time= -p ` twice, 6 seconds apart, and observe the clock advancing on a process with no session running.
## Workaround
A reaper on a 30-minute `StartInterval` launch agent. It maps each process to its session — via `--resume=` in argv, or by matching process start time against the transcript's creation time — and kills only processes whose own transcript has been idle past a threshold, never touching the most recently active session:
reap-stale-claude-sessions.py
```python
# Maps pid -> session transcript, reaps only sessions idle beyond --idle-hours.
procs = session_processes() # ps, filtered to .../claude-code/.../MacOS/claude
tx = transcripts() # ~/.claude/projects/*/.jsonl -> (birth, mtime)
newest = max(tx, key=lambda u: tx[u][2])
for p in procs:
uuid = p["resume"] or match_by_birth_time(tx, p["started"], window=300)
if uuid and uuid != newest and now - tx[uuid][2] > idle_limit:
os.kill(p["pid"], signal.SIGTERM)
```
This is a bandage over a lifecycle bug, though — a scheduled run that finishes should exit on its own.
## Impact
With 9 scheduled tasks on daily-or-faster cadences, this reaches ~2.3 cores and 2.7 GB within three days of uptime, and grows linearly until the app is restarted. Earlier reporters on #54626 hit worse — one reported (2026-05-28) a kernel-level Jetsam event on macOS in which the accumulation drove the machine out of memory and the kernel jettisoned ~1,000 processes, including system daemons.
Guida per i contributori
Nessuna guida per i contributori indicizzata per questo repository
Direzione di ricerca
Begin with the scheduled-task reproduction and inspect the process lifecycle around the bundled claude process and its disclaimer helper. Use `pgrep -x claude` and repeated `ps -o time= -p ` samples to confirm the orphan and CPU behavior. Done means completed scheduled runs exit and no orphaned processes continue consuming CPU.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- macos, python
- Ambito
- cli, desktop, operating-systems
- Tipo di issue
- Bug
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Stato di attività
- Attiva
- Chiarezza
- Abbastanza chiara
- Idoneità per principianti
- 45/100