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

Resolved 💬 8 comments Opened Dec 6, 2025 by melderan Closed Feb 27, 2026

[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)

<details>
<summary>Click to expand full scrollback</summary>

=== 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 ===

</details>

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

View original on GitHub ↗

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