Large paste in long-context session causes unrecoverable TUI freeze
Summary
When a large paste (~196KB) pushes a long-context session past the compaction threshold, auto-compact fails, the suggested recovery ("Press esc twice to go up a few messages and try again") also fails, and the TUI freezes permanently — requiring kill -9 of the terminal emulator.
Reproduction Steps
- Run a session until token count reaches ~145K+ (near the compaction threshold of ~167K)
- Paste a large block of text (~150KB+, ~4,400 lines)
- Token count jumps past the effective window (e.g., 198K > 180K)
- Auto-compact fires and fails:
Error: Conversation too long. Press esc twice to go up a few messages and try again. - Follow the suggested recovery: press Esc twice, use the message-selector to rewind to before the paste
- Manual compact also fails with the same error
- TUI becomes unresponsive — no input accepted, no recovery possible
- Only fix:
kill -9from another terminal
Debug Log Evidence
Session 61bd4f39-7241-4b51-9f0d-7523e384ac1f, version 2.1.39, macOS Darwin 25.2.0.
Token state before paste:
autocompact: tokens=146295 threshold=167000 effectiveWindow=180000
After paste (196KB, 4,466 lines):
autocompact: tokens=198718 threshold=167000 effectiveWindow=180000
Auto-compact failure:
[ERROR] Error: Error: Conversation too long. Press esc twice to go up a few messages and try again.
at yhT (/$bunfs/root/claude:3303:939)
at async tPB (/$bunfs/root/claude:3388:2545)
Manual compact failure (after following the Esc-Esc suggestion):
[ERROR] Error: Error: Conversation too long. Press esc twice to go up a few messages and try again.
at yhT (/$bunfs/root/claude:3303:939)
at async <anonymous> (/$bunfs/root/claude:3602:56)
...
[ERROR] Error: Error: Error during compaction: Error: Conversation too long. Press esc twice to go up a few messages and try again.
at <anonymous> (/$bunfs/root/claude:3603:189)
at async n08 (/$bunfs/root/claude:1989:3696)
at async YXB (/$bunfs/root/claude:1989:1064)
at async vk8 (/$bunfs/root/claude:7276:2509)
at async HyR (/$bunfs/root/claude:7274:3516)
at async Zx8 (/$bunfs/root/claude:7415:23321)
at async OkR (/$bunfs/root/claude:7415:22473)
Third attempt — same result:
[ERROR] Error: Error: Conversation too long. Press esc twice to go up a few messages and try again.
at LPB (/$bunfs/root/claude:3305:808)
at async <anonymous> (/$bunfs/root/claude:7430:8084)
at async j (/$bunfs/root/claude:7277:263)
Rendering death spiral — the paste expanded the virtual screen to ~6,000 rows:
High write ratio: blit=0, write=849312 (100.0% writes), screen=5962x158
Slow render: 100.2ms, screen: 5962x158, damage: 158x5962, changes: 1623525
Every render frame wrote 849K+ cells with 0% blit reuse. This continued until the process was killed.
Root Causes
- Compaction death loop: When the paste pushes tokens past the effective window, compact needs to make an API call — but the conversation is already too long for that API call. The error suggests "go up a few messages," but compact fails from the rewound position too. There is no escape from this state.
- Rendering death spiral: The 196KB paste creates a ~6,000-row virtual screen. At 849K writes per frame and 100ms+ per render, the TUI spends 100% CPU painting and becomes unresponsive.
- No paste size guard: 196KB / 4,466 lines enters the conversation without pre-validation. Large pastes should be rejected, truncated, or stored as file references.
Suggested Fixes
- Paste size validation: Reject or warn on pastes that would push past the effective window
- Graceful compaction fallback: If compact fails, offer to discard the last message rather than looping on the same error
- Render throttling: Cap rendering for pathologically large screen buffers (849K writes/frame is unsustainable)
- The Esc-Esc recovery path must actually work: If the UI suggests rewinding as recovery, that path needs to handle the "too long" state gracefully
Environment
- Claude Code version: 2.1.39 (auto-updated to 2.1.42 during the crash)
- OS: macOS Darwin 25.2.0
- Terminal: iTerm2
- Platform: darwin arm64
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗