Main-thread CPU spin (100-140%+) persists for hours after a long background Bash task completes (v2.1.222, macOS arm64)
Summary
After a long-running background Bash task with a large subprocess tree completes (e.g. a ~25–40 min test suite launched via run_in_background), the Claude Code CLI's main thread enters a sustained CPU spin (100–140%+) that never settles — it keeps the machine hot for hours until the session process is killed manually. Observed repeatedly across sessions and days; reproduced today with diagnostics attached.
Environment
- Claude Code: 2.1.222 (desktop-app-managed binary:
~/Library/Application Support/Claude/claude-code/2.1.222/claude.app/Contents/MacOS/claude --output-format stream) - macOS 15.5, Apple Silicon (arm64)
Repro (as observed, several occurrences over recent days)
- In an interactive session, run a long shell command as a background task (
run_in_background: true). In our case: a Pythonunittestsuite of ~6,200 tests taking 25–40 min, which itself forks many short-lived subprocesses. Stdout is redirected to a file, so the harness-visible output is small (the task output files are ≤345 KB — output volume is not the trigger). - Let the task complete (exit 0, completion notification delivered normally).
- Watch the
claudeprocess afterward: CPU stays pegged at 100–140%+ indefinitely — including while the session sits idle between turns — until the process is killed.
Diagnostics from today's occurrence
ps: the session'sclaudeprocess showed CPU time 55:59 against an elapsed lifetime of 42:29 — i.e. >130% average for its entire life, far exceeding the actual interactive work done.- No orphaned children: the suite's subprocess tree was fully reaped (no leftover python/node/chromium processes). The burn is in the CLI process itself.
sample <pid> 3: all 2,406 samples oncom.apple.main-thread, in a tight call graph inside the (stripped)claudebinary — a pure CPU spin, no syscall/IO wait at the top of the stack:
2406 Thread DispatchQueue_1: com.apple.main-thread (serial)
+ 2406 start (in dyld)
+ 2406 ??? (in claude) load address 0x104ea0000 + 0xa61388
+ 2406 ??? (in claude) + 0x10f6e68
+ 2406 ??? (in claude) + 0x10fcf70
+ 2406 ??? (in claude) + 0x5735ec
+ 2406 ??? (in claude) + 0x117a6ec
+ 2288 ??? (in claude) + 0xeef3bc
+ ! 2208 ??? (in claude) + 0x10b8314
+ ! : 1582 ??? (in claude) + 0x830ec0
...
(Full sample output available on request.)
Impact
A part-time operator's laptop runs hot for hours after every heavy background task; multiple long-lived sessions compound it (any of them can enter this state after such a task). Workarounds in use: running scheduled test suites outside Claude Code entirely (launchd), launching in-session long jobs fully detached (nohup … & disown) instead of harness-tracked background tasks, and closing sessions promptly.
Expected
After a background task completes and its notification is delivered, the CLI returns to an idle event loop (~0% CPU).