Linux/X11: one copy writes the clipboard twice (OSC 52 and xclip), and the two race for selection ownership

Status Open
Reported on v2.1.280
Maintainer reply None cached
Activity 4 comments · opened Sep 22, 2026

Summary

On Linux/X11, a single copy from the Claude Code TUI writes the system clipboard twice,
by two mechanisms that then race each other for ownership of the X selection:

  1. an OSC 52 escape sequence, which the terminal acts on by taking the CLIPBOARD selection;
  2. a pair of xclip processes, xclip -selection clipboard and xclip -selection primary,

spawned roughly 0.2 to 0.9 seconds later, which take both selections.

On X11 only one client can own a selection, so the later write takes it from the earlier
one. The terminal then reports that its write failed, and the text ends up wherever the
winner of the race put it.

With Alacritty the failure is visible as a warning that takes over the message bar:

[WARN ] [alacritty] Unable to store text in clipboard: Failed to set new owner of XCB selection

Evidence

I logged every change of X selection ownership together with every xclip process spawn,
resolving each owner to its process while it still held the selection.

A single drag-copy produces, in order:

CLIPBOARD -> <terminal pid>        (the OSC 52 write)
SPAWN      xclip -selection primary
CLIPBOARD -> <a new xclip>         (the xclip write, 0.7s later)
SPAWN      xclip -selection clipboard
SPAWN      xclip -selection primary
ALACRITTY  Unable to store text in clipboard: Failed to set new owner of XCB selection

The xclip processes belong to the Claude Code process group, so both writes come from
Claude Code itself. The terminal is only carrying out the OSC 52 request.

Setting osc52 = "Disabled" in the terminal removes one of the two writers. Counted over
comparable periods of copying, with nothing else changed:

| | xclip copies | times the terminal took the clipboard | warnings |
|---|---|---|---|
| before | 46 | 10 | 4 |
| after | 50 | 0 | 0 |

So the terminal's involvement came entirely from OSC 52, and the race disappears when only
one writer is left.

Impact

  • A copy can silently end up holding the wrong text, since which writer wins is a race.
  • The terminal's message bar fills with clipboard errors that look like a terminal fault.
  • Each copy leaves two more xclip processes serving the selections.

Environment

Claude Code 2.1.280, Linux, X11, Alacritty 0.13.2, tmux 3.7c, a clipboard manager running.

Expected

One copy should produce one clipboard write. Either use OSC 52 or use the external helper,
not both; if both are wanted as a fallback, the second should run only when the first is
known to have failed, rather than concurrently.

Workaround

Disable OSC 52 clipboard writes in the terminal, which leaves xclip as the only writer.
The cost is that programs which can only copy through OSC 52, ssh sessions above all, lose
the clipboard in that terminal.

View original on GitHub ↗

4 Comments

ismael-albaiti · 23 days ago

Extra detail that makes this reproducible: the copy is triggered by a mouse
drag in fullscreen rendering ("tui": "fullscreen"), with copyOnSelect at
its default of true, so finishing the selection copies automatically. Every
such drag produces both writes: the OSC 52 sequence and the xclip pair.

ismael-albaiti · 23 days ago

Three follow-ups, one of which narrows the severity.

The terminal's warning is partly its own bug. Alacritty reports "Failed to
set new owner of XCB selection" through a racy ownership check, fixed upstream
in alacritty/alacritty#6978 (merged, in 0.18.0-dev, not in a release yet).
Tested here: when the warning fires, the copied text is on the clipboard
anyway. So the double write is not losing text in this setup, and the visible
part of it is noise rather than data loss.

The double write is still real, and it is not free. Every copy produces two
writers, ownership of the X selection changes hands two to three times per
copy, and two xclip processes are left serving the selections. Where a
clipboard manager is running, each copy can land in history more than once, and
anything else writing at that moment loses the race for real.

copyOnSelect = false does not stop it. With it off, a drag no longer
copies, but an explicit copy still fires both writes and the race is unchanged.

Related, possibly the same root cause: #74214 (the same OSC 52 write emitted
twice), #41954 (TUI selection writing the clipboard on every render while
streaming), #57654 (OSC 52 writes CLIPBOARD but never PRIMARY), #80184 (a copy
reporting success while never writing).

ismael-albaiti · 23 days ago

Closing this. The visible symptom turns out to be a racy ownership check in the
terminal (alacritty/alacritty#6978, fixed upstream in 0.18.0-dev), and the
copied text does land here, so this is not losing data. The duplicate write
itself is already covered by #74214 and #41954.

ismael-albaiti · 23 days ago

Reopening. The terminal's warning being partly its own bug does not make the
double write right: every copy still spawns two writers, the X selection
changes hands two to three times per copy, and two xclip processes are left
behind. On a terminal without the upstream fix, which is every released
version, the user sees a clipboard error on every copy, and any other program
writing at that moment loses the race for real.

Refusing OSC 52 in the terminal is what stopped it here, at the cost of losing
escape-sequence copying entirely. That is a workaround for something the
application should not be doing twice.