[Bug] Clipboard write conflicts with Windows Terminal copy in RDP sessions
Bug Description
Windows: Claude Code rewrites the clipboard after the terminal has already copied, which breaks pasting into RDP sessions.
Environment: Windows 11 Pro 26200.9168, Claude Code 2.1.233 (also reproduced on 2.1.232 and 2.1.228), Windows Terminal 1.24.11911.0 (copyOnSelect false), Windows PowerShell 5.1, mstsc to a Windows Server.
Symptom: text selected and copied inside Claude Code cannot be pasted into an RDP session - the remote clipboard is left EMPTY, losing what was there before. Copying from an ordinary tab of the same Windows Terminal window works fine, so it is not the terminal, the RDP channel, the clipboard formats or the characters.
Measured by polling GetClipboardSequenceNumber every 15 ms during one copy:
22:56:38.604 seq=335 owner=WindowsTerminal 708 B CF_UNICODETEXT, CF_LOCALE, CF_TEXT, CF_OEMTEXT
22:56:38.834 seq=346 owner=powershell 708 B + DataObject, Ole Private Data
22:56:38.880 seq=347 owner=NONE 708 B + DataObject, Ole Private Data
22:56:49.948 seq=352 owner=WindowsTerminal 370 B (plain dir copy, one state, pastes fine)
Windows Terminal puts the selection on the clipboard first, in the ordinary form that crosses RDP. About 230 ms later a short-lived powershell.exe writes the same 708 bytes again with OLE formats on top, then exits. mstsc has already started transferring the first version to the server; the content is swapped underneath it, the transfer aborts, and the remote clipboard ends up empty. One write always works; two writes always fail.
Workaround: hold Shift while selecting, so Windows Terminal owns the selection and Claude Code never performs its second write - then pasting into RDP works. Also fixable after the fact with: Set-Clipboard -Value (Get-Clipboard -Raw)
Request: on Windows, skip Claude Code's own clipboard write when the terminal has already copied the selection, or make the second write optional.
Environment Info
- Platform: win32
- Terminal: null
- Version: 2.1.232
- Feedback ID: 24b73e48-6919-4642-ab26-b2bf8d649dab
Errors
[]Showing cached comments. Read the full discussion on GitHub ↗
3 Comments
Still reproduces on 2.1.237 (Win 11 Pro 26200, WT 1.24.11911.0,
copyFormatting: none). Two additions:Remote side measured. Immediately after a Claude Code copy, on the RDP server
[Windows.Forms.Clipboard]::GetDataObject().GetFormats($true)returns onlyTerminal Services Private Data— mstsc sends an empty format list, so the remote never learns text exists. After a Notepad or plain-WT-tab copy the same call showsUnicodeText.Why the second write is harmful. The spawned helper is Windows PowerShell 5.1, whose
Set-Clipboarduses WinForms →OleSetClipboardthenOleFlushClipboardon exit. That's two clipboard states ~50 ms apart (owner=powershell withDataObject/Ole Private Data, then owner=none), landing ~200 ms after Windows Terminal's own clean Win32 write. pwsh 7'sSet-Clipboardis a single Win32SetClipboardDataand crosses RDP fine — so even short of not double-writing, preferringpwshor calling Win32 directly would avoid the race.Also note this hits the client side (Claude Code on the laptop, pasting into mstsc sessions), not just session hosts. Shift+select (so WT owns the selection) confirmed as a workaround.
Still reproduces on 2.1.241.
Text copied in Claude Code on Windows never reaches the RDP client — clipboard is set by a short-lived owner, breaking rdpclip synchronization
Environment
Summary
When text is selected and copied inside Claude Code running full-screen (alternate screen buffer, mouse mode active — so Claude Code itself handles the selection/copy, not the terminal), the copied text can be pasted into any application inside the VM, but never arrives at the RDP client machine. Copying the very same text from Notepad or from a plain Windows Terminal selection syncs across RDP fine.
Steps to reproduce
rdpclip.exerunning).Set-Clipboard (Get-Clipboard -Raw)in the VM) → pasting on the RDP client now works.Reproducibility: 100%.
Diagnosis
The Win32 clipboard was inspected immediately after each kind of copy (enumerating raw formats via
EnumClipboardFormats/GetClipboardData/GlobalSize, and queryingGetClipboardOwner).After the failing Claude Code copy
After a working Windows Terminal selection copy (control)
Interpretation
CF_UNICODETEXT.DataObject+Ole Private Dataformats and a NULL clipboard owner: the clipboard was set through the OLE clipboard (OleSetClipboard) by a process/window that was destroyed immediately afterward. This is the signature of a short-lived clipboard helper (as spawned, e.g., by theclipboardynpm package on Windows).WM_CLIPBOARDUPDATE,rdpclip.exeannounces the formats to the client, and the actual bytes are fetched from the clipboard owner later, on demand. Because the owner is already gone when rdpclip processes the update, the announce/fetch fails silently and the client never receives the data.WM_RENDERALLFORMATS) — local apps read that rendered data directly. Only the RDP boundary is affected.Confirming experiment
Re-setting the byte-identical text from a live, persistent process:
immediately makes the text pastable on the RDP client. Same data, different owner lifetime → the owner lifetime is the root cause.
Expected behavior
Text copied in Claude Code reaches the RDP client like text copied from any other Windows application.
This bug is incredibly annoying, @bcherny .