You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug] Hook subprocess cleanup causes 100% CPU freeze on task interruption #55609
Refining the repro for the long-running 100% CPU freeze in 2.1.x (cross-ref public issues #27415 and #18532).
I now think this is hook-related, not just TaskStop-related.
Repro (4 steps, ~60 sec):
Have any hook configured in ~/.claude/settings.json (SessionStart / SessionEnd / Stop / PreToolUse / PostToolUse — especially ones running shell scripts)
Start a Claude session
Run any backgrounded bash tool
Interrupt — Ctrl-C, ask Claude to kill the task, or close the tab while the tool is mid-flight
100% CPU spin every time, force-kill required. Vanilla claude installs with no hooks seem much less likely to trigger.
5-minute test for the hypothesis (anyone on your team can run this):
mv ~/.claude/settings.json ~/.claude/settings.backup.json
echo'{}'>~/.claude/settings.json
claude
# (run + interrupt a backgrounded task)
mv ~/.claude/settings.backup.json ~/.claude/settings.json
If freeze stops with vanilla settings and reproduces with hooks, root cause is in the hook-subprocess + interrupt cleanup path. That would also explain why engineers on stock dev boxes don't reproduce on the first try, while users with AgentOps / custom MCP / status-line wrappers hit it daily.
I have a fresh forensic capture from 2026-05-02: independent 1Hz monitor logged the entire userland stalling for 24 seconds during the freeze. macOS 26.4.1 / M5 / 32 GB / claude 2.1.126. Happy to share.
Environment Info
Platform: darwin
Terminal: ghostty
Version: 2.1.126
Feedback ID: 53400c39-c176-4667-83ae-be548fa1e5d6
Note on auto-attached errors: the in-app /bug flow auto-attached two prompt is too long: 1006407 tokens > 1000000 maximum errors. Those are unrelated to this bug — they're context-overflow errors from a long-running session in this same window. They're not part of the freeze repro. Stripped from this issue body to avoid confusing the diagnosis.
Disclosure: I build AgentOps on top of Claude Code; filing as a daily user.
Quick add — quantitative scope, in case "happens multiple times a day" reads as anecdotal.
While diagnosing this morning I had a freeze-capture monitor running. Between 08:32 and 12:05 PDT today (~3.5 hours of active dev work), the monitor caught 21 distinct freeze events across 5 separate claude PIDs (28428, 42495, 47974, 55383, 99538). It's not a flaky thing that happens daily — it's a freeze every ~10 minutes when actively using claude with hooks configured.
System-load evidence:
Baseline 1-min load average (idle Mac): 3.37
During freeze peaks: l1=18.99, l1=18.51, l1=13.58 (5.6× baseline)
Threshold for "system stalled" trips: load > 6.74
Process-starvation evidence (the strongest single piece): the freeze-capture monitor itself hit fork: retry: Resource temporarily unavailable repeatedly while trying to spawn sample/vm_stat to capture state. That's macOS refusing to allocate new process slots. Not just claude was stuck — the kernel was rejecting fork() system-wide. The monitor's own bash interpreter was waiting on retry loops.
Sample of one stuck claude (PID 77747, taken 2026-05-02 08:27:44, claude 2.1.126, macOS 26.4.1):
2,561 thread samples on main thread (com.apple.main-thread, serial)
All 2,561 in the same call path: + 0x6569a0 → 0xe37c6c → 0x849910 → ...
Same syscall-loop signature as @smconner's Linux x86_64 gcore disassembly upthread
I have the full forensic dir — 7 freeze snapshots, the 21-event log, sample profiles for 5 PIDs, vm_stat captures, top.log, fork-failure stdout — happy to share with whoever picks this up.
Caught the parent PID red-handed in a system spindump while reproducing the 4-step repro from this issue body. macOS 26.4.1 / M5 / 32 GB / 2.1.126 / Ghostty.
Main thread 1000/1000 samples in __posix_spawn → __socketpair → setsockopt → __close_nocancel. Kernel turnstile waits name pgrep and spindump children. Footprint +1577 MB in 10s. kill -9 to recover.
Full forensic write-up and root-cause discussion: #52253 (comment). The repro in this issue body is the userland trigger for that bug.
External mitigation note while the root cause inside Claude Code is being narrowed:
The class of failure here — agent CLI leaves child processes spinning until force-kill — is catchable at the OS layer. On 2026-05-26 I hit a related pattern (load avg spiked to 307 from un-reaped iOS simulator children, also M5 / macOS 26.5 / Ghostty) and ended up writing a small LaunchAgent + wrapper combo to keep it from happening again. Open-sourced as https://github.com/IgorGanapolsky/mac-yolo-safeguards.
For the hook-cleanup-on-interrupt pattern @boshu2 reproduces specifically: the wrapper's stuck-loop watchdog kills the parent if it stays above 80% CPU for 2 minutes straight, catching the spinning state before manual force-kill is needed. The LaunchAgent only shuts down simulators — never touches GUI apps (no chance of losing unsaved IDE work). MIT, zero telemetry, install/uninstall is 4 symlinks.
Doesn't fix the root cause and is no substitute for a fix inside Claude Code, but takes the freeze out of the recovery loop while this gets diagnosed.
This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.
Activity
github-actions commentedon May 2, 2026
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
boshu2 commentedon May 2, 2026
Quick add — quantitative scope, in case "happens multiple times a day" reads as anecdotal.
While diagnosing this morning I had a freeze-capture monitor running. Between 08:32 and 12:05 PDT today (~3.5 hours of active dev work), the monitor caught 21 distinct freeze events across 5 separate claude PIDs (28428, 42495, 47974, 55383, 99538). It's not a flaky thing that happens daily — it's a freeze every ~10 minutes when actively using
claudewith hooks configured.System-load evidence:
Process-starvation evidence (the strongest single piece): the freeze-capture monitor itself hit
fork: retry: Resource temporarily unavailablerepeatedly while trying to spawnsample/vm_statto capture state. That's macOS refusing to allocate new process slots. Not just claude was stuck — the kernel was rejectingfork()system-wide. The monitor's own bash interpreter was waiting on retry loops.Sample of one stuck claude (PID 77747, taken 2026-05-02 08:27:44, claude 2.1.126, macOS 26.4.1):
com.apple.main-thread, serial)+ 0x6569a0 → 0xe37c6c → 0x849910 → ...gcoredisassembly upthreadI have the full forensic dir — 7 freeze snapshots, the 21-event log, sample profiles for 5 PIDs, vm_stat captures, top.log, fork-failure stdout — happy to share with whoever picks this up.
boshu2 commentedon May 2, 2026
Caught the parent PID red-handed in a system spindump while reproducing the 4-step repro from this issue body. macOS 26.4.1 / M5 / 32 GB / 2.1.126 / Ghostty.
Main thread 1000/1000 samples in
__posix_spawn → __socketpair → setsockopt → __close_nocancel. Kernel turnstile waits namepgrepandspindumpchildren. Footprint +1577 MB in 10s.kill -9to recover.Full forensic write-up and root-cause discussion: #52253 (comment). The repro in this issue body is the userland trigger for that bug.
IgorGanapolsky commentedon May 28, 2026
External mitigation note while the root cause inside Claude Code is being narrowed:
The class of failure here — agent CLI leaves child processes spinning until force-kill — is catchable at the OS layer. On 2026-05-26 I hit a related pattern (load avg spiked to 307 from un-reaped iOS simulator children, also M5 / macOS 26.5 / Ghostty) and ended up writing a small LaunchAgent + wrapper combo to keep it from happening again. Open-sourced as https://github.com/IgorGanapolsky/mac-yolo-safeguards.
For the hook-cleanup-on-interrupt pattern @boshu2 reproduces specifically: the wrapper's stuck-loop watchdog kills the parent if it stays above 80% CPU for 2 minutes straight, catching the spinning state before manual force-kill is needed. The LaunchAgent only shuts down simulators — never touches GUI apps (no chance of losing unsaved IDE work). MIT, zero telemetry, install/uninstall is 4 symlinks.
Doesn't fix the root cause and is no substitute for a fix inside Claude Code, but takes the freeze out of the recovery loop while this gets diagnosed.
boshu2 commentedon May 28, 2026
@IgorGanapolsky thank you! will try it out tonight. Crazy this still has yet to be fixed
github-actions commentedon Jun 30, 2026
Closing for now — inactive for too long. Please open a new issue if this is still relevant.
github-actions commentedon Sep 2, 2026
This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.