[BUG] Linux/VTE (Ptyxis, GNOME Terminal): copy-on-select reports "N characters copied" but never writes the clipboard — OSC 52 ignored, wl-copy fallback unawaited
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report
- [x] I am using the latest version of Claude Code
What's Wrong?
On VTE-based terminals (Ptyxis, GNOME Terminal, Tilix, Terminator…), copy-on-select shows "N characters copied" but the system clipboard is never written. The success message is emitted unconditionally — neither copy path is verified.
Both paths fail on this platform:
1. OSC 52 — silently ignored by VTE. This is the primary emission (the return of the setClipboard function). VTE does not implement OSC 52 clipboard writes, so the sequence is swallowed with no error.
Standalone repro, no Claude Code involved — run in Ptyxis/GNOME Terminal on Wayland:
$ wl-copy --clear
$ printf '\033]52;c;%s\007' "$(printf 'HELLO' | base64 -w0)"
$ wl-paste
# ← empty. On kitty/foot/WezTerm this prints HELLO.
I also verified it against a live session by injecting the sequence directly into the Claude Code pty (/proc/<pid>/fd/1):
clipboard cleared -> []
wrote OSC 52 to pty -> write ok
clipboard after OSC 52 -> [] # nothing
2. wl-copy fallback — fire-and-forget, never awaited, never checked. From the 2.1.217 bundle:
async function dT(e){ // setClipboard
let t = Buffer.from(e,"utf8").toString("base64");
if(!t6r()) yhu(e); // native copy — NOT awaited
await lMg(e); // tmux buffer
...
return cw(bS.CLIPBOARD,"c",t) // OSC 52 — the actual return value
}
function yhu(e){
let t = { input: e, useCwd: false, timeout: 2000 }; // spawn helper: SIGTERM after 2s
switch(Lt()){
case "linux":
if(typeof K0e !== "string")
AQi().then(()=>{ if(typeof K0e === "string") yhu(e) }); // async detection
else if(K0e === "wl-copy")
Jr("wl-copy",[],t), Jr("wl-copy",["--primary"],t); // no --foreground
...
}
}
async function AQi(){ // tool detection, async
if(process.env.WAYLAND_DISPLAY && await Ny("wl-copy")){ K0e = "wl-copy"; return }
if(process.env.DISPLAY){ /* xclip, xsel */ }
K0e = null;
}
Three problems here:
yhu(e)is not awaited and its exit code is never inspected. Whatever happens, the "copied" message still renders.wl-copyis spawned without--foreground, undertimeout: 2000/killSignal. On Wayland the clipboard is served by a surviving process — the source client must stay alive to answer the compositor's data request. Observed after a copy-on-select: nowl-copyprocess remains, and the selection is not retrievable.- First copy of a session is a no-op.
K0eis undefined, so the first call only kicks off async detection and returns; the copy depends on a retry firing later. This is a large part of why it appears intermittent ("works maybe 1 in 10 times").
What Should Happen?
- Do not report success unless a copy path actually succeeded.
wl-copy/xclip/xselshould be awaited and their exit code checked; when every path fails (or only unverifiable OSC 52 was attempted on a terminal known not to support it), surface a failure instead of "N characters copied". - Spawn
wl-copy --foregrounddetached (or otherwise let the serving process outlive the 2s timeout) so the Wayland selection survives. - Resolve the clipboard-tool detection once at startup, so the first copy of a session isn't a silent no-op.
Steps to Reproduce
- Fedora 42 (or any Wayland session), terminal Ptyxis or GNOME Terminal,
wl-clipboardinstalled. - Start
claude. - Drag-select any text in the TUI. UI shows "N characters copied".
- Paste anywhere (
Ctrl+Shift+V, or runwl-paste). - Actual: clipboard unchanged / empty. Expected: the selected text.
ps -eo pid,args | grep wl-copy→ no surviving process.
Additional Information
Impact. On VTE terminals there is currently no working in-TUI copy, and the UI actively misreports success — you retry, it says "copied" again, and nothing lands. Compounding it: mouse reporting is enabled, so a plain drag never reaches the terminal's own selection either.
Workaround (reliable, bypasses Claude Code entirely): hold Shift while dragging so VTE takes the selection, then Ctrl+Shift+C.
Note on copyOnSelect: false — not a workaround here, because of #77259 (the fullscreen renderer doesn't consult that gate).
Related but distinct:
- #77259 —
copyOnSelect: falseignored by the fullscreen renderer (about suppressing the copy; this issue is about the copy failing while reporting success). - #70550 — asks to prefer OSC 52 over
wl-copy; on VTE that would make this worse, since OSC 52 is a dead end there. Any fix should keep the native path on VTE. - #74214 — duplicate OSC 52 emission.
- #66957, #70857 — mouse capture / alternate-screen breaking terminal selection generally.
Claude Code Version
2.1.217 (native install)
Platform
Linux x86_64 — Fedora 42, kernel 6.17.8
Operating System
Fedora Linux 42
Terminal/Shell
Ptyxis 48.5 (VTE) on Wayland, TERM=xterm-256color, bash. Session is local (not SSH). wl-clipboard and xclip both installed and working when invoked manually. "tui": "fullscreen".
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗