[Bug] Fullscreen drag-select blocks TUI when DISPLAY points to unresponsive X socket

Status Open
Reported on v2.1.257
Maintainer reply None cached
Activity 0 comments · opened Sep 1, 2026

Bug Description

Fullscreen drag-select blocks the whole TUI when DISPLAY points at an X socket that never answers

Summary

In the fullscreen renderer, finishing a drag selection can block the entire
Claude Code process. The highlight stays on screen, keypresses are ignored,
Escape does nothing, and the only way out is to kill the terminal. The cause
is the Linux native clipboard path: when DISPLAY is set and neither xclip
nor xsel is installed, the bundled clipboard-napi addon's
setLinuxClipboardText is called synchronously with no timeout. If the X
socket accepts the connection but never completes the handshake, that call
never returns and the event loop is stuck.

This is easy to hit in a devcontainer reached through VS Code Remote-SSH plus
Remote-Containers. The Remote-Containers server creates
/tmp/.X11-unix/X<N> inside the container and sets DISPLAY=:<N> in
terminals. When the client machine has no X server behind the forwarding,
the socket accepts and then hangs forever.

Environment

  • Claude Code 2.1.257 (BUILD_TIME 2026-09-01T05:28:54Z, GIT_SHA 2c673eef).

Same code path is present in 2.1.219 and 2.1.231.

  • Linux x64 devcontainer, VS Code 1.134.0 integrated terminal

(TERM_PROGRAM=vscode), Remote-SSH into a Coder workspace, then
Remote-Containers.

  • tui: fullscreen in settings.json.
  • DISPLAY=:20, no xclip/xsel/wl-copy installed.

Steps to reproduce

  1. Create a Unix socket that accepts connections and never replies, and point

DISPLAY at it. For example DISPLAY=:20 with a listener on
/tmp/.X11-unix/X20 that never writes. (In my case VS Code's
Remote-Containers server owns that listener.)

  1. Run claude with the fullscreen renderer enabled.
  2. Drag-select any text with the mouse and release.

Expected

Selected text is copied (OSC 52 or a native tool) and the session keeps
responding. If the native path cannot reach the display, it fails fast and
falls back to OSC 52.

Actual

After the mouse release, no OSC 52 sequence is emitted, the process sits in
poll (wchan do_sys_poll), and it stops reacting to keyboard input and to
further mouse events. The last rendered frame is the selection highlight, so
it looks like a stuck selection or a frozen terminal.

Evidence

| DISPLAY | Result |
|--------------------|----------------------------------------------------------|
| :20 (hangs) | no OSC 52, wchan do_sys_poll, 0 bytes after a keypress |
| unset | OSC 52 emitted, keeps responding |
| :0 (refused) | OSC 52 emitted, keeps responding |

From the bundle: the Linux clipboard probe picks wl-copy, then xclip,
then xsel, then the addon whenever DISPLAY matches ^(unix)?:. The copy
path is copySelectionNoClear -> setClipboard -> native Linux copy and the
addon call is recordAddonWrite(addon.setLinuxClipboardText(text) !== false),
synchronous on the main thread.

Workarounds that confirm the cause

  • unset DISPLAY before launching: selection and copy work.
  • CLAUDE_CODE_DISABLE_MOUSE=1: removes in-app selection, so the clipboard

path never runs.

  • /tui default: classic renderer, same effect.

Suggested fix

Do the addon write off the main thread with a bounded timeout, or probe the
display with a short timeout before choosing the addon. The forwarded X
socket case is common enough with VS Code remote setups that fail-fast
matters more than getting the native copy right. Existing issues #61936 and
#72173 describe the same symptom and attribute it to mouse tracking; the
mouse tracking is only what makes the in-app selection happen.

Environment Info

  • Platform: linux
  • Terminal: vscode
  • Version: 2.1.257
  • Feedback ID: c0b4ce39-ecc4-4a04-85e3-cdc9d7ad9eb9

Errors

[]

View original on GitHub ↗