You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
OSC 52 clipboard copy doesn't work in tmux when allow-passthrough is off #19982
OpenCode's "copy to clipboard" (drag to select → copy) doesn't work when running inside tmux with allow-passthrough off. The UI shows "copied to clipboard" but the content never reaches the local system clipboard.
Environment
OpenCode: v1.3.6
OS: Linux (remote dev machine, accessed via SSH)
Terminal: iTerm2 (macOS)
Multiplexer: tmux 3.4
tmux config: set-clipboard on, allow-passthrough off
Root Cause
OpenCode's writeOsc52 function detects tmux via $TMUX env var and wraps the OSC 52 sequence in a DCS passthrough:
When tmux has allow-passthrough off (the default), the DCS passthrough sequence (\x1BPtmux;...\x1B\\) is silently dropped. The OSC 52 never reaches the outer terminal.
Other tools like Neovim handle this correctly — they rely on tmux's set-clipboard on forwarding mechanism instead of DCS passthrough, so OSC 52 works regardless of the allow-passthrough setting.
Expected Behavior
OpenCode should fall back to sending the raw OSC 52 sequence when allow-passthrough is not available, letting tmux's set-clipboard on handle the forwarding (same path that works for Neovim).
Workaround
TMUX= opencode
Unsetting $TMUX makes OpenCode skip the DCS passthrough wrapping. The raw OSC 52 is then correctly intercepted and forwarded by tmux's set-clipboard on.
Suggested Fix
In writeOsc52, prefer raw OSC 52 over DCS passthrough when running in tmux. DCS passthrough should only be used for sequences that tmux's set-clipboard won't forward (like bracketed paste, etc.). For OSC 52 specifically, set-clipboard on already provides the correct forwarding behavior:
functionwriteOsc52(text){constbase64=Buffer.from(text).toString("base64");constosc52=`\x1B]52;c;${base64}\x07`;// Don't use DCS passthrough for OSC 52 — tmux's set-clipboard on handles forwardingprocess.stdout.write(osc52);}
Or, if DCS passthrough is needed for other reasons, detect whether it's actually available (e.g., by querying allow-passthrough via tmux control mode) before using it.
If your issue is distinct (e.g., specifically about the allow-passthrough off case rather than the /dev/tty forwarding issue), please clarify how it differs from the above.
Yeah but that then doesn't work for users having allow-passthrough on. There is no way to detect what tmux options are set via ssh. It's different for every other user and environment.
Additional finding: the tmux passthrough wrapper also has a double ESC byte bug
I investigated the same issue with tmux pipe-pane hex dump capture and found an additional subtle code bug in the writeOsc52() function beyond the allow-passthrough discussion.
The template \x1BPtmux;\x1B${osc52}\x1B\\ has an extra \x1B (ESC) byte between tmux; and ${osc52}. Since osc52 itself starts with \x1B (ESC ]52;c;...), the actual bytes sent are:
Expected: ESC P tmux; ESC ]52;c;base64 BEL ESC \
Actual: ESC P tmux; ESC ESC ]52;c;base64 BEL ESC \
^^
double ESC — NOTE the extra \x1B in the template:
`\x1BPtmux;\x1B${osc52}\x1B\\`
^^ this ESC is the bug
Confirmed by tmux pane capture:
Offset Hex ASCII
0518: 1b 50 74 6d 75 78 3b ESC P t m u x ;
0525: 1b ← extra ESC byte
0526: 1b 5d 35 32 3b 63 3b ESC ] 5 2 ; c ; (OSC52 begins)
This extra ESC can cause the terminal to reject the OSC52 sequence.
The same template pattern appears in the GitHub source at: packages/opencode/src/cli/cmd/tui/util/clipboard.ts
Fix: Change \x1BPtmux;\x1B${osc52}\x1B\\ to \x1BPtmux;${osc52}\x1B\\ (remove the \x1B before the OSC52 payload).
Workaround: env -u TMUX opencode (unset $TMUX to skip the DCS wrapper entirely, letting tmux set-clipboard on handle raw OSC52 forwarding).
Activity
github-actions commentedon Mar 30, 2026
This issue might be a duplicate of existing issues. Please check:
writeOsc52function and DCS passthrough behaviorIf your issue is distinct (e.g., specifically about the
allow-passthrough offcase rather than the/dev/ttyforwarding issue), please clarify how it differs from the above.kommander commentedon Mar 30, 2026
Yeah but that then doesn't work for users having allow-passthrough on. There is no way to detect what tmux options are set via ssh. It's different for every other user and environment.
NewbieToEverything commentedon May 19, 2026
Additional finding: the tmux passthrough wrapper also has a double ESC byte bug
I investigated the same issue with
tmux pipe-panehex dump capture and found an additional subtle code bug in thewriteOsc52()function beyond theallow-passthroughdiscussion.The template
\x1BPtmux;\x1B${osc52}\x1B\\has an extra\x1B(ESC) byte betweentmux;and${osc52}. Sinceosc52itself starts with\x1B(ESC ]52;c;...), the actual bytes sent are:Confirmed by tmux pane capture:
This extra ESC can cause the terminal to reject the OSC52 sequence.
The same template pattern appears in the GitHub source at:
packages/opencode/src/cli/cmd/tui/util/clipboard.tsFix: Change
\x1BPtmux;\x1B${osc52}\x1B\\to\x1BPtmux;${osc52}\x1B\\(remove the\x1Bbefore the OSC52 payload).Workaround:
env -u TMUX opencode(unset$TMUXto skip the DCS wrapper entirely, letting tmuxset-clipboard onhandle raw OSC52 forwarding).github-actions commentedon Jul 19, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.
feat(tuika): mouse subsystem — selection, clicks, hit-testing, OSC 52…