claude-code icon indicating copy to clipboard operation
claude-code copied to clipboard

[BUG] CLI hangs on paste from accessibility/voice-to-text tools - bracketed paste mode mishandling

Open melderan opened this issue 1 month ago • 2 comments

[BUG] CLI hangs on paste from accessibility/voice-to-text tools - bracketed paste mode mishandling

Environment

  • Claude Code version: 2.0.59 (Homebrew)
  • OS: macOS 15.2 (Darwin 25.1.0)
  • Architecture: ARM64 (Apple Silicon)
  • Terminal: iTerm2
  • Accessibility tool: Handy - open source voice-to-text using Whisper (injects text via clipboard + Cmd+V)

Summary

Claude Code becomes completely unresponsive when receiving pasted text from voice-to-text accessibility software. The TUI fails to properly handle bracketed paste sequences, causing the closing marker [201~ to appear raw in the input prompt. After multiple paste attempts, the process hangs permanently and requires kill -9 to terminate.

Root Cause Evidence

Terminal scrollback with timestamps shows the bracketed paste END marker appearing raw in the prompt:

[12/05/2025, 19:39:48] > [201~

This indicates Claude Code is not properly consuming the bracketed paste sequence:

  • Expected: \e[200~ (start) + content + \e[201~ (end) should be processed invisibly
  • Actual: The opener and content are swallowed, only [201~ leaks through as literal text

Each time this happens, the TUI crashes/resets (banner reprints). After ~9 attempts, it hangs completely.

Steps to Reproduce

  1. Start Claude Code in terminal
  2. Use voice-to-text software that injects text via clipboard + simulated Cmd+V (e.g., Handy)
  3. Speak for ~30-45 seconds
  4. Observe: CLI shows > [201~ in prompt, then resets
  5. Repeat a few times - CLI eventually hangs permanently

Terminal Scrollback (Sanitized, with timestamps from iTerm2)

Click to expand full scrollback
=== CLAUDE CODE SESSION START ===

   313->[12/05/2025, 19:37:38] $HOST:$PROJECT $USER$ claude
   314->[12/05/2025, 19:37:39]
   315->[12/05/2025, 19:37:39]  [ASCII LOGO]   Claude Code v2.0.59
   316->[12/05/2025, 19:37:39]  [ASCII LOGO]   Opus 4.5 - Claude Max
   317->[12/05/2025, 19:37:39]   [ASCII LOGO]  ~/$PROJECT
   318->[12/05/2025, 19:37:39]
   319->[12/05/2025, 19:37:39]   Debug mode enabled
   320->[12/05/2025, 19:37:39]   Logging to: $HOME/.claude/debug/$UUID.txt

=== PASTE ATTEMPT #1 - Note the [201~ appearing in prompt ===

   339->[12/05/2025, 19:39:48]
   340->[12/05/2025, 19:39:48] ─────────────────────────────────────────────────────────
   341->[12/05/2025, 19:39:48] > [201~
   342->[12/05/2025, 19:39:48] ─────────────────────────────────────────────────────────

=== TUI RESETS - Banner reprints ===

   343->[12/05/2025, 19:40:08]
   344->[12/05/2025, 19:40:08]  [ASCII LOGO]   Claude Code v2.0.59
   345->[12/05/2025, 19:40:08]  [ASCII LOGO]   Opus 4.5 - Claude Max
   ...

=== PASTE ATTEMPT #2 ===

   350->[12/05/2025, 19:42:29]
   351->[12/05/2025, 19:42:29] ─────────────────────────────────────────────────────────
   352->[12/05/2025, 19:42:29] > [201~
   353->[12/05/2025, 19:42:29] ─────────────────────────────────────────────────────────

=== Pattern continues through attempts #3-#8 ===

=== PASTE ATTEMPT #9 - FINAL, TRIGGERS PERMANENT HANG ===

   416->[12/05/2025, 20:04:00]
   417->[12/05/2025, 20:04:00] ─────────────────────────────────────────────────────────
   418->[12/05/2025, 20:04:00] > [201~
   419->[12/05/2025, 20:04:00] ─────────────────────────────────────────────────────────
   420->[12/05/2025, 20:04:00]

=== PROCESS HANGS - All subsequent lines are empty with frozen timestamp ===

   421->[12/05/2025, 20:03:46]
   422->[12/05/2025, 20:03:46]
   ... 54 empty lines, frozen timestamp, process is hung ...
   476->[12/05/2025, 20:03:46]

=== END - Process required kill -9 to terminate ===

Process Diagnostics

Using macOS sample on the hung process:

Call graph:
    8588 Thread_main  DispatchQueue_1: com.apple.main-thread
    + 8588 start  (in dyld)
    +   8588 ???  (in claude)
    +     8549 kevent64  (in libsystem_kernel.dylib) + 8

99%+ of samples show the process blocked in kevent64 - waiting on kernel I/O that never completes. The process cannot respond to Ctrl+C or other signals.

How the Accessibility Tool Works

Handy (and similar voice-to-text tools) inject transcribed text by:

  1. Copying text to system clipboard
  2. Simulating Cmd+V keystroke via Enigo library
  3. Restoring original clipboard contents

This is a standard paste operation that works correctly with other terminal applications.

Related Issues

  • #11611 - Same symptom (blocked in write(), required kill -9)
  • #3134 - Bracketed paste mode corruption
  • #2552 - Paste + rapid Enter freeze
  • #4772 - v1.0.63 paste freeze
  • #1490 - Original large paste hang (reportedly fixed in 1.0.8, but issue persists)

Impact

This bug blocks users who rely on voice input for accessibility. The paste mechanism used is standard and identical to manual Cmd+V - the issue is in Claude Code's handling of bracketed paste sequences.

Expected Behavior

Claude Code should:

  1. Properly consume bracketed paste sequences (\e[200~...\e[201~)
  2. Not display escape sequence fragments in the prompt
  3. Handle paste input gracefully without crashing/resetting the TUI
  4. Remain responsive to interrupt signals even during paste handling

melderan avatar Dec 06 '25 04:12 melderan

Found 2 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/11611
  2. https://github.com/anthropics/claude-code/issues/3134

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

github-actions[bot] avatar Dec 06 '25 04:12 github-actions[bot]

Correction: macOS Version

The reported OS version was incorrect. Here are the accurate details:

Reported: macOS 15.2 (Darwin 25.1.0)
Actual: macOS 26.1 Tahoe (Darwin 25.1.0)

The Darwin kernel version 25.1.0 corresponds to macOS 26.x (Tahoe), not macOS 15.x (Sequoia which uses Darwin 24.x).

Full system info:

ProductName:    macOS
ProductVersion: 26.1
BuildVersion:   25B78
Darwin Kernel:  25.1.0
Architecture:   ARM64 (Apple Silicon M4 Max)

The bracketed paste handling issue has been reported across multiple macOS versions (see related issues), so this is likely not version-specific.

melderan avatar Dec 06 '25 10:12 melderan

I can reproduce this reliably in iTerm2 3.6.6 just by pasting 100 lines of input into claude. I'm running macOS 26.2 and Claude Code v2.0.71:

  1. Open iTerm2 window
  2. Run printf "Test line %d\n" {1..100} | pbcopy
  3. Run claude
  4. Paste and observe claude is now hung (won't respond to any keyboard input)
  5. Also observe that all 100 lines were pasted.. the last line in the input buffer is "Test line 100"
  6. Run pkill claude and observe that Claude dies and the iTerm2 window is now usable

But I can't reproduce this using macOS Terminal 2.15 or Ghostty 1.2.3. Claude Code behaves differently there:

  1. Open Terminal window
  2. Run printf "Test line %d\n" {1..100} | pbcopy
  3. Run claude
  4. Paste and observe claude is still responsive to keyboard input after pasting
  5. Also observe that claude's input buffer now says [Pasted text #1 +100 lines] instead of the literal Test line [..]

The "Pasted text" summary feature for large pastes was working fine for me in iTerm2 a couple months ago, but that was on older iTerm2, claude, and macOS.

When this problem was happening yesterday for me when trying to paste many lines into claude, I was seeing the [201~ literal text in the input buffer instead of the expected "Pasted text" summary or the text I was trying to paste. Not sure why it's behaving a little differently for me right now.. nothing has changed as far as I know.

fjarlq avatar Dec 17 '25 07:12 fjarlq