Scheduled task sessions (Desktop local agent mode) never exit after completing; processes accumulate until the host runs out of memory
Environment
- Claude Desktop (macOS): 1.34493.1
- Bundled Claude Code runtime: 2.1.237 (
~/Library/Application Support/Claude/claude-code/2.1.237) - macOS: Darwin 25.6.0, Mac mini (Apple Silicon), 16GB RAM
- Feature: Claude Desktop scheduled tasks (local agent mode), cron
*/30 * * * *
Summary
After updating to Desktop 1.34493.1 / runtime 2.1.237, every session spawned by a recurring scheduled task finishes its work normally but its claude process never exits. With a 30-minute cron, processes accumulate indefinitely. Each idle leaked process also keeps consuming ~7-15% CPU and ~100MB RSS.
Within ~48 hours we accumulated 106 leaked processes (~473% CPU, ~5.3GB RSS combined), which pushed the 16GB host into swap thrash (load avg 67, 87% sys CPU, 18MB free RAM) and took down unrelated production services running on the same machine (Docker containers began timing out).
Evidence that the session itself completes
- Session transcripts (JSONL under
~/.claude/projects/...) end with a normal final assistant message 5-20 minutes after spawn, then stop advancing. The process stayed alive 20+ hours after that (until killed manually). - Processes were spawned exactly on the task's cron cadence (every 30 min + fixed jitter), launched as:
claude --output-format stream-json --input-format stream-json --permission-mode auto ...with local-agent-mode plugin dirs. - All leaked processes exit cleanly on SIGTERM.
Regression timeline (strong version correlation)
- The same scheduled task ran ~200 times over several prior weeks with no process accumulation.
- Desktop updated to 1.34493.1 on Aug 21 02:14 (local); runtime 2.1.237 was installed Aug 21 11:05 — the same minute the first leaked session spawned (11:05:19). Every session from that point on leaked. The task definition itself was unchanged in behavior (single-line prompt invoking a skill).
Expected
When a scheduled-task session finishes its turn, the runner should reap the process (as pre-update versions did).
Workaround we deployed
A launchd job that SIGTERMs task sessions older than 40 minutes (matched by process cwd). Works, but users running recurring local scheduled tasks on always-on machines will hit this hard, and the per-process idle CPU burn makes it worse.
Happy to provide sanitized transcripts/process listings if useful.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗