[BUG] Claude Code v2.1.9 Complete Freeze - 100% CPU, Main Thread Stuck in Infinite Loop (macOS ARM64)

Open 💬 29 comments Opened Jan 16, 2026 by smconner

Summary

Claude Code v2.1.9 session became completely unresponsive, consuming 100% CPU and ~7GB RAM for nearly 2 hours. The main thread is stuck in an infinite loop with no progress. This appears to be a continuation of the freeze/hang issues reported in earlier versions.

Keywords for discoverability: freeze, hang, stuck, unresponsive, 100% CPU, spinning, infinite loop, main thread blocked, macOS, ARM64, Apple Silicon, M4, Bun runtime, kill -9 required

---

Related Issues

This bug is related to and may be a regression of:

| Issue | Title | Version | Status |
|-------|-------|---------|--------|
| #1554 | Hanging/Freezing in the middle of work | v1.0.10 | OPEN |
| #6474 | Unresponsive hang with 120% CPU usage | v1.0.89, v2.0.x | OPEN |
| #11339 | 100% CPU in interactive mode on macOS | v2.0.36 | Closed (Fixed) |
| #11377 | Memory leak with 143% CPU after 14 hours | v2.0.22 | Closed |
| #4580 | 100% CPU during multi-agent task JSON serialization | v1.x | OPEN |
| #6705 | claude doctor hangs indefinitely, 100% CPU | v1.0.95 | OPEN |
| #10481 | Complete UI Freeze - ReadFileUtf8 I/O Block | v2.0.28 | OPEN |

---

Environment

| Component | Value |
|-----------|-------|
| Claude Code Version | 2.1.9 |
| Platform | macOS 15.7.3 (Build 24G419) |
| Architecture | ARM64 (Apple Silicon) |
| CPU | Apple M4, 10 cores |
| RAM | 32GB |
| Kernel | Darwin 24.6.0 |
| Terminal | /dev/ttys011 |

---

Symptoms

  • Complete UI freeze - No response to any input
  • 100% CPU on single core - Main thread spinning indefinitely
  • ~7GB memory consumption (RSS), 2GB physical footprint
  • Cannot interrupt - Only kill -9 terminates the process
  • Work lost - Must force quit and lose session state
  • Network connections remain open - Server-side appears fine

---

Process State When Frozen

PID     CPU%    MEM%    RSS        STATE   ELAPSED     COMMAND
36202   100.1   20.9    6.7GB      R+      01:55:44    claude

| Metric | Value |
|--------|-------|
| CPU Time Consumed | 8+ minutes |
| Wall Clock Time Frozen | ~2 hours |
| Launch Time | 13:24:28 |
| Sample Time | 15:20:12 |

---

Stack Sample Analysis

A 10-second sample (8500 samples at 1ms intervals) shows 100% of samples on the main thread in a tight loop.

Thread Summary

| Thread | Role | Status |
|--------|------|--------|
| Main Thread (com.apple.main-thread) | Event loop | 🔴 SPINNING - 8500/8500 samples |
| Bun Pool 0-7 | Worker threads | Idle |
| HTTP Client | Network | Idle |
| File Watcher | FS events | Idle |
| JavaScriptCore libpas scavenger | GC | Idle |
| Heap Helper Threads (x3) | GC | Idle |

Hot Path (Main Thread)

The main thread is stuck in this call path (symbols stripped, showing offsets):

8500 start (in dyld)
└─ 8500 ??? (in 2.1.9) + 0x3f90
   └─ 8500 ??? (in 2.1.9) + 0x536c
      └─ 8500 ??? (in 2.1.9) + 0x26a430
         └─ 8500 ??? (in 2.1.9) + 0x1121cd0
            └─ 8500 ??? (in 2.1.9) + 0x2ab770
               └─ ... (deep into JS/Bun runtime)

System Calls in Hot Path

_platform_memmove (libsystem_platform.dylib)     ← Memory copy operations
__bzero (libsystem_platform.dylib)               ← Memory zeroing
pthread_getspecific (libsystem_pthread.dylib)    ← Thread-local storage
os_unfair_lock_lock/unlock (libsystem_platform)  ← Lock operations
task_info (libsystem_kernel.dylib)               ← Process info queries

This pattern suggests:

  • Possible infinite loop with repeated memory allocations
  • Or runaway JSON serialization/parsing
  • Or regex catastrophic backtracking
  • Or busy-wait polling loop (similar to #11339)

---

Network State

The process maintained active connections to Anthropic servers:

tcp4  192.168.1.136:59404 -> 160.79.104.10:443  ESTABLISHED
tcp4  192.168.1.136:58472 -> 160.79.104.10:443  ESTABLISHED

IP 160.79.104.10 confirmed as Anthropic infrastructure (ARIN: AP-2440). This indicates the freeze is client-side - server connections remain healthy.

---

Open File Descriptors

FD   TYPE   NAME
0-2  CHR    /dev/ttys011 (terminal)
12   TCP    -> 160.79.104.10:443 (Anthropic API)
37   TCP    -> 160.79.104.10:443 (Anthropic API)
43   REG    ~/.claude/settings.local.json
47   REG    ~/.claude/history.jsonl

---

System State (Not Overloaded)

Load Average: 1.78, 1.64, 1.60
CPU: 20.70% user, 12.33% sys, 66.96% idle
RAM: 31GB used, 654MB free (32GB total)
Processes: 740 total, 5 running

The system was not under heavy load - this is isolated to the Claude Code process.

---

Reproduction

Unable to determine exact trigger - the freeze occurred during normal interactive usage. However, based on related issues, potential triggers include:

  • Search/grep operations (#6474)
  • Multi-agent/Task tool usage (#4580)
  • Large context or file operations (#1554)
  • Interactive prompt mode (#11339)

---

Workaround

Force kill the frozen process:

kill -9 $(pgrep -f "claude" | head -1)

---

Suggested Fixes

Based on analysis and related issues:

  1. Add watchdog timer - Detect main thread stalls > N seconds
  2. Implement operation timeouts - Prevent infinite loops in parsing/serialization
  3. Use async I/O properly - Avoid busy-wait polling (fix from #11339 may have regressed)
  4. Add SIGINT handler - Allow graceful interrupt even when stuck
  5. Memory operation limits - Cap allocation loops

---

Attachments

Full stack sample available (175KB, 8500 samples over 10 seconds). Happy to provide if needed.

---

For Other Users Experiencing This

If you're finding this issue because Claude Code froze on you:

  1. To kill a frozen session:

```bash
# Find the PID
ps aux | grep claude

# Kill it (only -9 works when frozen)
kill -9 <PID>
```

  1. To capture diagnostic info before killing:

```bash
# Get stack sample (macOS)
sample <PID> -f /tmp/claude_sample.txt

# Get process info
ps -p <PID> -o pid,ppid,state,time,etime,pcpu,pmem,rss,command

# Get open files
lsof -p <PID>
```

  1. Workarounds that may help:
  • Use shorter sessions
  • Avoid very large file operations
  • Try claude --resume instead of --continue after recovery

---

/cc @bcherny (assigned on #1554)

View original on GitHub ↗

29 Comments

github-actions[bot] · 6 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/11473
  2. https://github.com/anthropics/claude-code/issues/3214
  3. https://github.com/anthropics/claude-code/issues/17540

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

richbradshaw · 6 months ago

M4 Pro Mac, getting same on 2.1.9. Running "claude" nothing happens - have to kill it.

superresistant · 6 months ago

I had few freezes yesterday and I opened other terminal with -c continue and the app refreshed.

acorbellini · 6 months ago

This issue appeared in recent versions of CC, since ~2.1.0 I'm getting increased number of freezes (many per day), sometimes when claude tries to read large files/command outputs, sometimes it just gets stuck after a Bash tool use.

richbradshaw · 5 months ago

My report was a mistake. I was sshed in and Claude had a macOS pop up saying it was an app from Internet and I needed to click yes. But Ui via ssh doesn't make that clear etc

genail · 5 months ago

It seems that it's somehow related to working with large files or MCP responses. For me, it's mostly when I do stuff with playwright.

albiol2004 · 5 months ago

Same here, HP Spectre x360 with arch and froze after using grep on a really big markdown file. Closing tab doesn't kill the process and in some cases just hitting the button to resume the conversation freezes too so I can't continue the same chat.

Krakazybik · 5 months ago

same issue when grep big xml, log, md files.

genail · 5 months ago

Worth mentioning: for me it started happening only after a while, once the conversation got bigger. I switched back to 2.0.x, which doesn’t have this bug. When I find a moment, I’ll try to grab a stack trace and process info (if possible).

jonaustin · 5 months ago

I finally gave up and switched back to 2.0.76; 100% reproducible freezing immediately went away.

2.1.12 was reproducibly freezing with 100% cpu on macos when reviewing a PR that had a large (>2k lines) VCR cassette diff.

Unfortunately 2.1.x appears "literally unusable" right now; only switched back to 2.0 because this happened multiple times in multiple different situations; this is really a show-stopper right now and makes claude code pretty much unusable.

ryanontheinside · 5 months ago
I finally gave up and switched back to 2.0.76; 100% reproducible freezing immediately went away.

i am trying this now. for me claude code has been 'literally unusable' for a couple of days.

for anyone else that wants to try this, i found claude code continually updated itself until i launched with this command $env:DISABLE_AUTOUPDATER=1; claude

rasmusrbj · 5 months ago

Additional reproduction details

Experiencing the same 100% CPU freeze, plus a variant where it silently crashes instead of freezing.

My environment:

  • Version: 2.1.19 (Homebrew cask) - also tested native installer
  • macOS: Darwin 25.2.0 (Apple Silicon)
  • Project-specific: Only happens in certain repositories, not all

Observations:

  1. Native installer: Freezes on first message - unusable
  2. Homebrew cask: Works initially, then freezes/crashes after idle + terminal switch

New variant - Silent crash:

  • Send message → "Germinating..." spinner appears
  • Process receives API response ("Stream started - received first chunk" in logs)
  • Process silently dies - no error, just returns to shell
  • Debug log stops with no error message

Tried:

  • Eliminating MCP servers - issue persists
  • Different projects - some work, some don't
  • Fresh terminal sessions - works initially, then fails

The project-specific nature suggests something about project size, file count, or configuration triggers this.

(Originally filed as #21006, closed as duplicate)

rasmusrbj · 5 months ago

Update: MCP ruled out as cause

Ran with CLAUDE_MCP_DISABLE=1 - same crash occurs.

The crash pattern is consistent:

  1. API request succeeds
  2. "Stream started - received first chunk" logged
  3. Last log entry is always: High write ratio: blit=X, write=Y (78%+ writes), screen=22x123
  4. Process silently dies - no error

This suggests the crash is in the rendering/display loop, not network or MCP related.

alexey-milovidov · 5 months ago

How to reproduce (happened four times already):

Clone ClickHouse repository:

git clone git@github.com:ClickHouse/ClickHouse.git
cd ClickHouse
git submodule init
git submodule update

Launch Claude:

claude

And prompt:

Investigate these failures: https://s3.amazonaws.com/clickhouse-test-reports/json.html?PR=95080&sha=d0fe81a5256549304f26dc529eec596edef89851&name_0=PR&name_1=Integration%20tests%20%28amd_asan%2C%20targeted%29

Result:
https://pastila.nl/?00694b87/3b05f313bb3cc002ee717649c370ad23#RWoIWr8G7hIgszGKzL6UQg==GCM

oxysoft · 5 months ago

Yeah this needs to be investigated asap, I just lost a couple days off my 300$ sub. Software completely incapacitated, completely locks up with no explanation. --debug is useless, seemingly no pattern. It eventually dies with SIGABRT I believe

oxysoft · 5 months ago

If I launch with a brand new .claude, then it works. After bisecting I found that the lockup is triggered by reintroducing simply the projects directory. However if I recall it seemed that even opening inside a brand new directory/project still produces the lockup. It's possible the index itself is causing it.

DavidWells · 5 months ago

My setup was working fine until it randomly stopped today mid-day. I think the auto-updater ran updated to 2.1.27 (not sure from which working version) and then I get the same 100% CPU utilization freeze issues on mac 15.1 (24B83)

I had to uninstall claude completely, install specific version npm install -g @anthropic-ai/claude-code@2.0.76 and turn off the auto-updater that is installing the bricked binary. Otherwise claude will work on the first run with 2.0.76 and install the broken 2.1.27 bin and the next claude run will freeze.

Added

"env": {
    "DISABLE_AUTOUPDATER": "1"
  }

to my settings for now and it seems to be working ok

tswymer · 5 months ago

Having this issue with 2.1.27 too, everything just freezes as soon as a prompt is submitted.

Downgrading (and disabling auto-update) to 2.1.23 works for me.

iamapfelbaum · 5 months ago

same issue, donwgrade to 2.1.23 worked

prestonbrown · 5 months ago

2.1.25 doesn't exhibit a hard freeze at startup... 2.1.27 does.

MorningLightMountain713 · 5 months ago

<img width="1160" height="112" alt="Image" src="https://github.com/user-attachments/assets/e39de142-abae-4fa1-a655-9cffe48d06ae" />

Honestly, it's just so tiring, surely this is not rocket science?

junaidtitan · 5 months ago

For those hitting the 100% CPU freeze on resume — this is often caused by the session JSONL file growing too large for efficient parsing. Progress entries, subagent outputs, and duplicate blocks accumulate without pruning.

Cozempic can reduce the file size before resume to prevent the freeze:

pip install cozempic
cozempic list                          # Find the problematic session
cozempic treat <session-id> -rx aggressive  # Dry-run first
cozempic treat <session-id> -rx aggressive --execute  # Apply with auto-backup

The aggressive tier applies all 13 strategies including mega-block trimming (>32KB blocks) and document dedup — useful when the session is already too large to resume normally. Backups are automatic.

greogory · 5 months ago

Linux x86_64 Core Dump Analysis — V8 Property Lookup Infinite Loop (v2.1.34)

Confirming the same bug on Linux x86_64 with Claude Code v2.1.34. I captured a full core dump via gcore before SIGKILL, providing instruction-level root cause.

Environment

| Component | Value |
|-----------|-------|
| Claude Code | 2.1.34 |
| Platform | CachyOS (Arch), Linux 6.18.9-2-cachyos |
| CPU | AMD (x86_64) |
| Binary | ~/.local/share/claude/versions/2.1.34 (statically compiled, stripped) |

Live Process State Before Kill

| Metric | Value |
|--------|-------|
| CPU | 54% sustained (single main thread) |
| RSS | 2.3 GB |
| Runtime | ~8 minutes before detection |
| TCP Connections | Zero (no API connection) |
| Disk Writes (5s sample) | 0 bytes |
| Disk Reads (5s sample) | ~92 KB (internal only) |
| SIGTERM | Ignored — required SIGKILL |

Syscall Profile (5-second strace)

 84.12%  futex           (2,249 calls)
  9.94%  restart_syscall (8 calls)
  2.97%  sched_yield     (3,975 calls)
  2.95%  madvise         (2,959 calls)
  0.01%  pread64         (2,197 calls)

Thread Analysis from Core Dump (30 threads)

| Group | Count | Address | Syscall | State |
|-------|-------|---------|---------|-------|
| Main (V8 JIT) | 1 | 0x4687efa in binary | userspace — not in any syscall | Spinning in V8 JIT code |
| libuv workers | 18 | 0x3041383 | futex(WAIT) on shared condvar 0x667a9e4 | Idle — all on same futex |
| Event loop | 1 | 0x3a4f03a | epoll_pwait2(fd=14) | Normal (EINTR from gcore) |
| V8/platform | 9 | 0x7f53af4b0872 in libc | futex (ERESTARTNOINTR) | Blocked on V8 internal mutexes |

Root Cause: V8 Property Descriptor Hash Table Loop

The main thread (Thread 1) was trapped in a tight V8 JIT-compiled loop doing a property descriptor lookup in a hash table. Disassembly:

;; Entry: read counter, check capacity
0x4687ea1:  mov  0x320(%rax),%ecx      ; entry count = 27
0x4687ea7:  cmp  $0x63,%rcx            ; capacity = 99
0x4687eab:  jae  0x4687f1b             ; overflow → slow path (never taken)

;; Store value and return (normal fast path)
0x4687eba:  lea  0x1(%rcx),%edx
0x4687ebd:  mov  %rdi,(%rax,%rcx,8)    ; store
0x4687ec1:  mov  %edx,0x320(%rax)      ; increment count
0x4687ec7:  pop  %rbp
0x4687ec8:  ret

;; Hash table probe path (where it's stuck)
0x4687ec9:  mov  0x1efbc38(%rip),%rdx  ; load hash table base
0x4687ed3:  mov  %rcx,%rsi             ; hash key
0x4687ee8:  movabs $0x1ffffffffffffffc,%r8  ; mask
0x4687ef2:  and  %rsi,%r8              ; compute bucket index
0x4687ef5:  mov  0x18(%rdx,%r8,1),%r8d ; load descriptor from bucket
0x4687efa:  shr  %cl,%r8d              ;  ← STUCK HERE: extract type bits
0x4687efd:  and  $0x3,%r8d             ; mask to 2-bit type tag
0x4687f01:  cmp  $0x1,%r8d             ; check if type == 1
0x4687f05:  je   0x4687ea1             ;  ← LOOPS BACK (tight loop)

The je at 0x4687f05 jumps back to 0x4687ea1, creating a tight CPU-bound loop. The V8 engine is repeatedly probing a property descriptor hash table (27 entries / 99 capacity) without ever yielding to the event loop.

Key Differences from macOS Report

| Aspect | Issue #18532 (macOS) | This Report (Linux) |
|--------|---------------------|---------------------|
| Network | Connections open | Zero TCP connections |
| Binary | Bun runtime | Node.js (statically compiled) |
| CPU | 100% single core | 54% (scheduler dependent) |
| Instruction | Stripped offsets only | Full x86_64 disassembly |

Conclusion

The main thread enters a V8-internal infinite loop in JIT-compiled code. All worker threads are properly idle on futex. The event loop thread is properly in epoll_pwait2. But because the main thread never returns from its JIT function, the event loop never gets a chance to process I/O events, timers, or signals (explaining why SIGTERM is ignored — the signal handler can't run).

This is a V8 engine-level bug (or V8 JIT miscompilation) rather than a JavaScript-level infinite loop, since the stuck code is in V8's internal property descriptor machinery, not user JS code.

synman · 3 months ago

New Reproduction: Post-MCP-Response CPU Spin with Full Forensics

Adding a detailed reproduction case to this issue. Filed separately as #36729 but this is the same class of bug.

Environment

| Component | Value |
|-----------|-------|
| Claude Code | Latest (updated 2026-03-19) |
| OS | macOS (Apple Silicon, Darwin 25.3.0) |
| Model | claude-opus-4-6 (1M context) |
| MCP Servers | Custom Python MCP server (isaac-mcp) + excel-stdio |

Reproduction

  1. Start Claude Code session with custom MCP server providing ~95 tools + excel-stdio (~25 tools)
  2. Submit a plan for execution (large user message ~16KB)
  3. Session executes 3 batches of parallel tool calls (Read, Bash, MCP) — all return normally
  4. Final MCP call report_proposals(filter="read") returns 2758 bytes of valid JSON
  5. CPU spin begins — process enters R+ state at 100%, never generates a response

Forensic Evidence (JSONL Transcript Analysis)

The session transcript (6b7a00f4-8d44-4adc-8e22-495502c64cbe) proves exactly where the failure occurs:

15:55:28  Session start — user submits plan (15,739 chars)
15:55:40  Batch 1: 6× parallel Read calls → all returned (33KB total)
15:55:57  Batch 2: 5× parallel Read calls → all returned (14KB total)
15:56:14  Batch 3: 4× parallel Bash calls → all returned (~0.5KB total)
15:56:22  Assistant generates text response (normal)
15:56:25  MCP call: report_proposals(filter="resolved") → 6,568 bytes returned
15:56:33  Assistant generates text response (normal)
15:56:33  MCP call: report_proposals(filter="read") → 2,758 bytes returned ← LAST TRANSCRIPT ENTRY
          *** CPU spin begins — no assistant response ever generated ***
12:09:00  Killed via kill -9 after 11.5 hours

Key proof: The MCP tool result IS in the transcript (line 68) — the data was received by Claude Code. The runtime failed during response generation, not during tool execution.

Process State When Hung

PID   PPID  STAT   %CPU  %MEM   RSS       ELAPSED   COMMAND
56980 21743 R+     100.3 1.9    1,284,416 11:22:08  claude --name claude-workspace

Two zombie children never reaped:

18413 56980 Z+  <defunct>
24510 56980 Z+  <defunct>

Ctrl-C and Esc completely non-functional. Only kill -9 terminated it.

Estimated API Payload at Time of Hang

| Component | Size |
|-----------|------|
| System prompt (governance rules chain) | ~123 KB |
| Tool definitions (~135 tools across 2 MCP servers + built-ins) | ~135 KB |
| Conversation history (23 tool results across 3 batches) | ~93 KB |
| System reminders (plan mode, compliance, per-turn injections) | ~20-30 KB |
| Total estimated API payload | ~580-600 KB |

Well within 1M context window. The triggering response was 2758 bytes — trivially small.

What This Adds to #18532

  1. Exact failure point identified: Post-tool-result, pre-response-generation. Not I/O blocked, not waiting on network — pure CPU spin during the model response processing phase.
  2. JSONL transcript proof: Unlike most reports that describe symptoms, this one has machine-readable evidence of every event up to the hang.
  3. Payload measurements: First report to quantify the full API payload at time of hang (~580KB).
  4. Zombie process evidence: Parent failed to reap children, suggesting the event loop broke entirely — not just slow, but structurally broken.
  5. Normal trigger: The response that triggered the hang was small, well-formed JSON. No edge cases in the data itself.

Narrowed Search Space

The bug is in Claude Code's response generation pipeline — the code path between "tool result received" and "assistant message produced." The tool result was valid. The payload was within limits. The process was running (R+), not sleeping (S). Something in this code path enters an infinite loop under certain conditions.

Cross-reference: #36729 (my detailed report), #34565 (different bug — tool never returns), #36469 (different bug — oversized response)

rajeshias · 3 months ago

I had to downgrade to 2.1.79 to stop claude code freezing my macOS

Edit: No downgrading worked for me sadly! it was still eating up my ram.

Edit2: I found out the issue is not solely with claude code, i have a lot of extensions in vs code, i uninstalled all of them and clean installed claude code latest version (2.1.85) and other essentials. Seems the issue is no more! The CPU is happy now

boshu2 · 2 months ago

Refinement on the "main thread infinite loop" diagnosis: a fresh 10s system spindump on 2.1.126 (macOS 26.4.1, M5, 32 GB) shows all 1000 main-thread samples in __posix_spawn → __socketpair → setsockopt → __close_nocancel — a syscall spawn loop, not a JS/V8 tight loop.

Kernel turnstile waits explicitly name pgrep children. The bug appears to be the tree-kill recursive pgrep storm tracked in #52253, not a JS-level infinite loop. Forensic detail: #52253 comment. Reproduces reliably with the 4-step repro in #55609.

hiddenlayer1 · 1 month ago

Hi @smconner — wanted to note a possibly-related observation, though I want to be careful: I don't have proof these are the same bug, just a pattern worth flagging for anyone debugging this thread.

In the context-window-misdetection cluster (#55504, #47019, #35677, #34143, #43989, #42375, #34332), Claude Code Desktop on Max plan with Opus 4.7 [1m] is treating the served context as ~200K (not the advertised 1M), which causes auto-compaction to fire at ~190K and cascade every single turn thereafter. In one 30-day window on my machine the cascade fired 602 times across 153 sessions, with one session compacting 29 times.

When a user issues /compact manually past ~350K in this cascade state, the slash command registers in ~/.claude/cache/compaction-log.jsonl with trigger: "manual" but the displayed context bar never moves and the session never returns to a usable state — it appears the manual /compact is queued behind the auto-cascade and never observably finishes. The runtime stays busy but the UI thread becomes effectively unresponsive for compaction purposes.

I can't confirm whether that's the same freeze you're describing in v2.1.9 (your case is platform:macos and predates the 1M variant), but the symptom shape — "Claude Code consumes CPU on the main thread and becomes unresponsive during/around compaction" — is similar enough that it might be worth checking if the auto-compact-cascade scenario is part of the freeze-cluster's root cause. If the compaction work item is non-cancellable and a second one stacks behind a first one that hasn't finished, that would explain both your hang and my "manual /compact never completes."

Comprehensive 30-day evidence on the primary tracker #55504: https://github.com/anthropics/claude-code/issues/55504#issuecomment-4525687708 — happy to share raw JSONL if it's useful for cross-referencing your repro.

Thank you for the very thorough freeze report — the main-thread-stuck framing is exactly the kind of detail that lets people connect dots across related bugs.

echo-layker · 29 days ago

Consolidating from my duplicate #68931 — adding macOS ARM64 sampling evidence that this is still present in a much newer build.

Env: Claude Code v2.1.177, macOS 15.7.3 (24G419), Apple Silicon (ARM64).

Symptom: three idle claude sessions simultaneously pinned at ~99.9% CPU with no prompt running; accumulated hours of CPU while idle; terminal became laggy / couldn't accept input.

Sampling (5× /usr/bin/sample on the worst pid, byte-for-byte identical → stable repeating state):

  • Main thread (com.apple.main-thread) sits in the event loop with kevent64 returning immediately and re-arming in a tight loop (varied return offsets) rather than blocking — the macOS equivalent of the setImmediate/non-blocking-poll busy-wait described in #17148 / #10493.
  • Top-of-stack is dominated by waiting/polling primitives with no single hot compute frame:
__psynch_cvwait   21560
__ulock_wait2     21560
kevent64           3796
mach_msg2_trap     2156

Recovery (same as #21006): opening a new Claude session knocked the stuck session out of the spin without killing it — the stuck PIDs immediately dropped to ~0.1% CPU and stopped accumulating CPU time. So a terminal state change (SIGWINCH / focus / foreground-pgrp) seems to break the loop.

Full 5 sample captures (no sensitive data — sample redacts user paths to /Users/USER/*, binary is stripped):
https://gist.github.com/echo-layker/1d38915d4cbdfa27de2672a21cc22f21

Aggravating factor: multiple long-lived idle sessions accumulating in the background made it far more frequent/impactful (cf. #11122).

IgorGanapolsky · 5 hours ago

Mac freezes / 100% CPU under coding agents is a class of failure we see a lot in multi-agent fleets (not only Claude Code).

If anyone lands here mid-incident on macOS:

  1. Check whether the host is thrashing under multiple agent processes (load average, jetsam / memory pressure), not only the single issue loop in the binary.
  2. Open-source host guards for agent Macs live in mac-yolo-safeguards (freeze rescue + runaway process guards; no telemetry in the guard kit).
  3. For behavioral repeat mistakes (same bad tool call forever), we use ThumbGate-style permanent gates on top of the host layer.

Free kit first. If you have one repeated production failure pattern that costs real hours/tokens and want a fixed paid diagnostic ($499, one pattern, written root-cause + which gates to install), public-safe intake: paid hardening inquiry or the Diagnostic Payment Link in the repo README.

Not affiliated with Anthropic — sharing because the freeze + infinite-tool-retry combo is the same class of reliability work we ship.