Sessions hang indefinitely in Metamorphosing state with 0 tokens

Resolved 💬 3 comments Opened Feb 16, 2026 by ronald-braunstein Closed Feb 20, 2026

Bug Report: Claude Code Sessions Hang in "Metamorphosing" State

Summary

Claude Code sessions frequently hang indefinitely in the "Metamorphosing" state with 0 tokens being transmitted, requiring manual termination.

Environment

  • OS: macOS Darwin 25.2.0
  • Claude Code Version: 2.1.16 (based on lsof output)
  • Model: Opus 4.5

Reproduction

This occurs intermittently during normal use. The pattern observed:

  1. Session runs normally for some time (in this case ~16 minutes of "brewing")
  2. Session enters "Metamorphosing" state
  3. Token counter shows "↓ 0 tokens" and never increases
  4. Session remains stuck indefinitely (observed 38+ minutes)
  5. CPU usage drops to near 0%
  6. Only way to recover is Esc/Ctrl+C or killing the process

Evidence

Screenshot shows session stuck at:

  • "Metamorphosing.. (esc to interrupt · 38m 1s · ↓ 0 tokens)"
  • Background command had completed (exit code 0)
  • PR was created successfully before the hang
  • Session was unresponsive

Connection Analysis

Using lsof monitoring, healthy Claude sessions show:

  • Multiple ESTABLISHED connections to 160.79.104.10:443 and 172.64.147.211:443
  • Active CPU usage (2-25%)

Suspected hung state characteristics:

  • ESTABLISHED connections may still show but no data flow
  • 0% CPU usage
  • 0 tokens received for extended periods

Impact

  • User work is blocked until they notice and manually terminate
  • No automatic timeout or recovery
  • No warning when connection becomes stale
  • Difficult to distinguish hung state from slow response

Requested Improvements

  1. Connection health monitoring: Detect when streaming connection stops receiving data
  2. Configurable timeout: Allow users to set max idle time before warning/reconnect
  3. Automatic reconnection: Attempt to recover from stale connections
  4. Visual indicator: Show connection health status in UI (not just token count)
  5. Logging: Better diagnostics for debugging hung states (without requiring OTEL setup)

Frequency

User reports this happens "often" - multiple times per week across different sessions.

Workaround

Monitor Claude processes externally using scripts like:

# Quick check for hung processes
for pid in $(pgrep -f "claude"); do
  cpu=$(ps -p "$pid" -o %cpu= 2>/dev/null)
  echo "PID $pid: CPU ${cpu}%"
done

Press Esc to interrupt when detected.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗