[BUG] Fullscreen TUI: mouse-selecting a long response silently drops 26-character runs when the drag auto-scrolls — `/tui default` fixes it

Status Open
Reported on v2.1.221
Maintainer reply None cached
Activity 2 comments · opened Aug 4, 2026

Summary

Selecting a long assistant response with the mouse and copying it silently loses text.
The loss is not random: across one measured incident, 11 separate runs vanished, each
exactly 26 rendered characters
. Nothing is mis-encoded and nothing is truncated at the
start or end — interior runs simply disappear, and blank runs appear where text had been.

This is not the known paste-side truncation reports (#49673, #49337, #51129, #46953,
which are Windows and paste-path). Pasting is fine here; the damage happens on the
copy side, and it survives into whatever you paste it into. The practical consequence
is real data loss: an agent in another session received the damaged text and had to stop
and ask for the missing rules to be re-sent.

Environment

| | |
|---|---|
| Claude Code | 2.1.221 |
| OS | macOS 26.5.2 (build 25F84), Apple Silicon (Mac17,7) |
| Terminal | iTerm2 3.6.11 — also reproduced in Warp v0.2026.07.08.17.54.stable_02 |
| Shell | zsh |
| Locale of the text | Hungarian (multi-byte UTF-8 throughout) |

Because two unrelated terminal emulators show the same failure, the terminal is not the
variable.

Measurement

Ground truth was recovered from the source session's own transcript
(~/.claude/projects/<slug>/<session-id>.jsonl, the message.content[].text blocks) and
diffed character-by-character against the clipboard contents (pbpaste). The eleven lost
runs:

 rendered  bytes  run
       26     28  'thé qúick brown fox jumps.'
       26     33  'á lázy dóg slééps néár it.'
       26     27  'páck my box with five jugs'
       26     30  'sphínx óf bláck qúartz jud'
       26     31  'hów véxíngly qúíck daft ze'
       26     26  'bright vixens jump; dozy f'
       26     29  'qúíck wáfting zephyrs vexe'
       26     30  'twó drívén jócks help fax '
       26     27  'fíve quacking zephyrs jolt'
       26     28  'thé jáy pig fox zebra and '
       26     28  'crázy Frédrick bought many'

The run contents above are stand-ins — the source text is from private work — but each one
reproduces the measured run exactly in both dimensions that matter: 26 rendered characters,
and the same UTF-8 byte count as the run it replaces. The lengths and byte counts are the
evidence; the wording is not.

Two properties of this table matter:

  1. Constant in characters (26), variable in bytes (26–33). A byte-level buffer or

throughput problem would be constant in bytes, and would eventually split a multi-byte
UTF-8 sequence. No character was ever mangled — every á í ó ő ű ö and the em dash
survived intact. So this is not a byte-stream problem.

  1. Where the surrounding rendered line could be reconstructed from a screenshot taken

just after the copy, all four reconstructible runs spanned columns 21–46 of their
line. Same start column, same end column, four different lines with unrelated content.

The damage was confined to the tail of the copied text; everything above that point was
byte-identical to the transcript.

Controls — four attempts that came back clean

Each of these was diffed the same way and had zero differences:

  1. Paste path. An 8250-byte payload placed on the clipboard with pbcopy and pasted

into the prompt: byte-identical. The paste path is not implicated.

  1. Mouse copy as such. A 40-line payload with a per-column fingerprint, printed by

Claude Code and mouse-selected within a single screen: byte-identical, every column
present.

  1. The same damaged source text, re-copied later after it had scrolled fully into

scrollback: byte-identical, twice.

  1. The same static response, tail region only, selected entirely within one screen so

the drag never ran off the edge: byte-identical to the transcript (1467 chars, 13 lines).

The differentiating variable

The failing selection was dragged bottom-up, past the top edge of the viewport, so the
view auto-scrolled during the drag
. Control 4 selected the same text from the same
static response without auto-scroll and was clean.

Caveat, stated plainly: control 4 also covered a smaller region, so selection size is not
fully excluded as a contributing factor.

One observation that constrains the mechanism: in the damaged copy, the affected lines
were space-padded to the pane width — but padding by itself does not indicate damage,
since the clean control 4 was padded on 12 of its 13 lines. Padding only means the copy
came from the screen cell grid rather than from scrollback.

Also ruled out: the source response was long finished and static when copied, so this
is not "the response was still being repainted".

Confirmed cause: fullscreen TUI's internal mouse selection

The failing session ran with "tui": "fullscreen" in ~/.claude/settings.json, with no
CLAUDE_CODE_DISABLE_MOUSE set, so mouse capture was active. Per #65844, in fullscreen
TUI the drag is handled by Claude Code's own selection rather than the terminal's; per
#71826, mouse capture takes click-drag away from the terminal in the first place.

A/B confirmation. Switching to /tui default and repeating the identical selection —
same static response, same bottom-up drag, same auto-scroll past the top edge — returned
the text with zero characters lost, against 11 lost runs in fullscreen. Nothing else
was changed. Diffed against the transcript, the only remaining differences were four
markdown emphasis markers that the terminal correctly does not render.

This also explains why two unrelated terminal emulators reproduced the bug identically:
neither of them was computing the selection. And it explains the shape of the loss — a
fixed column band (26 columns, consistently starting at column 21 where the
surrounding line could be reconstructed) is what a column-arithmetic error in the
auto-scroll path of an internal selection produces, and is nothing like a byte-stream
defect.

Expected behaviour

Selecting and copying a response should yield the text as emitted, regardless of whether
the drag caused the viewport to scroll.

Reproduction

  1. Run with "tui": "fullscreen" (the default "tui": "default" does not reproduce).
  2. In a Claude Code session, produce a response several screens long (prose, so it wraps).
  3. Scroll back to it after it has finished and is static.
  4. Starting at the bottom of the response, drag the mouse selection upward past the top

edge of the viewport so the view auto-scrolls, up to the start of the response.

  1. Copy, and diff the clipboard against the same text in

~/.claude/projects/<slug>/<session-id>.jsonl.

Because the source response is static, this replays on demand.

Workarounds

  • /tui default — removes the symptom entirely (see the A/B above), at the cost of

fullscreen mode.

  • /copy — never round-trips through the rendered screen, so it is safe in either mode.

Both are worth documenting, because mouse selection is the obvious thing to reach for and
it fails silently: there is no marker, no ellipsis, nothing to notice until a downstream
reader finds a sentence that has lost its middle. In my case the damaged text was pasted
into another agent, which then acted on rules whose middles were missing.

View original on GitHub ↗

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