Desktop app scheduled-task runs never exit their claude session process; they accumulate at ~5% CPU each until the Mac saturates

Status Open
Reported on v2.1.247
Maintainer reply None cached
Activity 0 comments · opened Sep 2, 2026

Environment: Claude Code 2.1.247 bundled with the macOS desktop app
(~/Library/Application Support/Claude/claude-code/2.1.247/claude.app/Contents/MacOS/claude),
macOS 15.6 (Darwin 24.6.0), Apple M2, 8 cores. Roughly 70 scheduled tasks
configured, cadences from hourly to weekly.

What happens: each scheduled-task run spawns a claude session process
(via Claude.app/Contents/Helpers/disclaimer -- .../MacOS/claude --output-format
stream-json --input-format stream-json --permission-mode auto ...
). When the
run finishes, the session shows isRunning: false in the app, but the process
does not exit. It idles at ~5% CPU in a kevent64 / mach_msg poll loop
(sample output available). Processes accumulate one per run.

Measured 2026-08-31 09:35 PT, 22 h after a reboot: 57 such session
processes (114 rows counting the disclaimer wrappers), only 3 sessions
actually running work; aggregate ~380% CPU of 800% available; load average
82; Activity Monitor 83.7% System, 0% idle. The leak refills at 2–16 processes
per hour (37 hourly samples over the following 36 h), so a reboot buys about a
day.

Expected: a finished scheduled run's process exits, as a terminal claude
-p
run does.

Workaround in place: an hourly launchd job kills session processes older
than 3 hours unless they are above 15% CPU. Load average is now ~5. Killing a
process loses nothing — the session resumes from its transcript on the next
message — which suggests the process is simply not being told to exit.

Reproduce: create a scheduled task that runs a one-line command hourly;
after a few hours, ps -axo pid,etime,pcpu,command | grep 'MacOS/claude ' shows
one live process per completed run, each with ~5% CPU and elapsed time
matching the run's start.

Evidence available on request: ps listing, sample of an idle process,
the reaper log with per-hour counts.

View original on GitHub ↗