Reproducing SSE streaming hang (#33949) — up to 50min queue lock on macOS 2.1.138
Environment
- OS: macOS Darwin 24.6.0 (Sequoia)
- Claude Code: 2.1.138
- Model: Claude Opus 4.7 (1M context)
- Mac load average (1min): 49.66 (3 active users, 66-day uptime)
- Network: Wi-Fi + occasional VPN
- Sessions opened in parallel: typically 4-10
Problem reproducing
I'm a designer (not a developer) using Claude Code daily. When I send a message and the agent starts processing, sending any subsequent message queues it indefinitely. I've measured wait times up to 50 minutes before the agent reads the second message.
What I've validated
Cross-referenced 3 open issues that together explain the symptom:
- #33949 — SSE
messages.stream()has no timeout/heartbeat. When TCP dies silently (Wi-Fi blip, VPN reconnect, system sleep), Node.js never receives an error → infinite wait. Hang rate analysis in that issue shows 2.4-4% in v2.1.69-2.1.74 and ~10-15% per hour in heavy use. - #16905 — ESC was disabled when queued messages exist (introduced v2.1.0). UI shows
(esc to interrupt)but key does nothing. - #36326 — Documentation says \"Enter to interrupt and steer\" but Enter only queues; never interrupts.
Empirical confirmation on my machine
Verified hang signature via lsof -p <claude_pid> — when stuck, the Node.js process shows zero TCP ESTABLISHED sockets while still running. The process is alive but the SSE stream is silently dead.
Workaround I now use (not a fix)
Custom shell script (claude_recover.sh) that detects \"zombie\" Claude Code processes (0 ESTABLISHED sockets + JSONL transcript idle >120s) and kills them safely (backing up the JSONL transcript first). Then I run /resume to continue the session.
Also added an optional macOS watchdog daemon (claude_sse_autorecover.sh) that polls every 30s and pops a confirmation dialog before killing — anti-false-positive triple guard (strict AND of sockets=0 + idle>120s + manual confirm).
This works as recovery but is not a fix — the root cause is upstream in cli.js where messages.stream() lacks a heartbeat/idle-timeout watchdog.
Request
Please prioritize fixing #33949 (the root cause). The proposed fix in that issue (30s idle timeout + heartbeat watchdog) would eliminate this entire class of bugs.
Issues #16905 and #36326 are downstream symptoms of #33949 + the v2.1.0 ESC behavior change.
Impact
Productivity loss is significant. I rely on Claude Code for daily work on a civic project (open-source anti-corruption transparency platform). A 50-minute wait per stuck message is not viable.
Happy to provide additional empirical data (hang frequency log, JSONL transcripts sanitized of sensitive content, etc.) if helpful.
Thanks for the great product — just need this one root-cause fix.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗