Interactive TUI crashes: screen width spirals unboundedly (100% write ratio)
Environment
- Claude Code version: 2.1.63 (Homebrew cask, macOS)
- OS: macOS (Apple Silicon, Ghostty terminal)
- Shell: zsh
- Auth: OAuth (Claude Max subscription)
- Permission mode:
--dangerously-skip-permissions(bypass)
Description
Claude Code crashes consistently in interactive mode while print mode (-p) works perfectly every time. The process hard-crashes mid-stream with no clean Stop event, no signal, no OOM kill, and no macOS crash report.
Root Cause Evidence
Debug logs show the internal render surface width growing unboundedly every render cycle while height stays constant:
[DEBUG] High write ratio: blit=0, write=12279 (100.0% writes), screen=167x81
[DEBUG] High write ratio: blit=0, write=12482 (100.0% writes), screen=171x81
[DEBUG] High write ratio: blit=0, write=12840 (100.0% writes), screen=182x81
[DEBUG] High write ratio: blit=0, write=13075 (100.0% writes), screen=188x81
In longer sessions, this spirals to screen=507x81 and screen=431x103 before the process dies.
Key observations:
- 100% write ratio, 0% blits — the entire screen is redrawn from scratch every frame because the render surface dimensions keep changing
- Width grows, height stays fixed — not consistent with actual terminal resizing
- No clean shutdown — the debug log ends abruptly mid-API-stream with no Stop event, no
Stopped caffeinate, no cleanup - No OS-level crash signal — no macOS crash report, no Jetsam/OOM kill, no SIGTERM/SIGKILL in system logs
Reproduction
- Run
claude --dangerously-skip-permissionsinteractively in Ghostty terminal - Send any prompt that triggers tool use (Glob, Bash, Read, subagents)
- Watch the debug log (
~/.claude/debug/<session>.txt) — screen width increases on everyHigh write ratioline - Process crashes within 30-120 seconds of active tool use
What does NOT cause it
Extensive elimination testing was performed:
- Print mode (
claude -p "say ok"): Never crashes. Confirmed across dozens of runs. - OAuth token: Re-authenticated with fresh token (all scopes:
user:profile,user:inference,user:mcp_servers). Still crashes. - MCP servers: Disabled all MCPs (google, playwright, memory, gitnexus). Only grepai remaining. Still crashes.
- Hooks: Disabled all project hooks and global hooks. Still crashes.
- Plugins: All plugins disabled (
enabledPlugins: {}). Still crashes. - Claude.ai MCP connectors: Disabled gate (
tengu_claudeai_mcp_connectors: false). Still crashes. - Shell wrapper: Tested with raw
/opt/homebrew/bin/claudebinary directly. Still crashes. - Terminal size locking: Attempted
stty cols 120 rows 40+trap '' WINCH. Still crashes.
Debug Log (clean session, minimal config)
Session e5d93d29-6072-4505-bccc-16ac8596388d.txt:
- Start:
22:43:21— clean startup, only grepai MCP, 0 plugins, 0 hooks 22:43:22— REPL mounted, session active22:44:16— User prompt submitted, API streaming begins22:44:16— FirstHigh write ratioatscreen=167x8122:44:26— Subagent (Explore) launched, tools executing (Glob, Bash, Read)22:44:29— Screen width at188x81, still growing22:44:40— Log ends abruptly mid-stream — no Stop, no cleanup
Total session duration: 79 seconds before hard crash.
Expected Behavior
The screen width should remain fixed at the terminal's actual column count. The render path should use blitting (partial updates) instead of full-screen rewrites when the terminal dimensions haven't changed.
Workaround
Use print/pipe mode (claude -p "prompt") or non-interactive mode. Interactive TUI is currently unstable.
This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗