From 2d3f555429935ffccdf23d9adae09ef7e0b85ca7 Mon Sep 17 00:00:00 2001 From: Shakti Date: Fri, 24 Jul 2026 10:28:37 +0530 Subject: [PATCH] fix: await wl-copy exit code and fall through to xclip on failure (#7009) The /copy command always set copied=true after spawning wl-copy without awaiting its exit code. When wl-copy fails (e.g. in a sandboxed environment that inherits WAYLAND_DISPLAY but not the socket), the xclip/OSC 52 fallbacks never ran because copied was already true. Fix: await the wl-copy spawn exit code and only claim success on exit code 0. On failure, fall through to the x11 clipboard fallback. Fixes #6872. --- packages/coding-agent/src/utils/clipboard.ts | 26 ++++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/packages/coding-agent/src/utils/clipboard.ts b/packages/coding-agent/src/utils/clipboard.ts index 9bb10d5c9..b991636a8 100644 --- a/packages/coding-agent/src/utils/clipboard.ts +++ b/packages/coding-agent/src/utils/clipboard.ts @@ -104,15 +104,25 @@ export async function copyToClipboard(text: string): Promise { try { // Verify wl-copy exists (spawn errors are async and won't be caught) execSync("which wl-copy", { stdio: "ignore" }); - // wl-copy with execSync hangs due to fork behavior; use spawn instead - const proc = spawn("wl-copy", [], { stdio: ["pipe", "ignore", "ignore"] }); - proc.stdin.on("error", () => { - // Ignore EPIPE errors if wl-copy exits early + // wl-copy with execSync hangs due to fork behavior; use spawn instead. + // Await the exit code and only claim success on a clean exit, so a + // failed wl-copy falls through to the xclip/OSC 52 fallbacks. + const wlCopyExit = await new Promise((resolve) => { + const proc = spawn("wl-copy", [], { stdio: ["pipe", "ignore", "ignore"] }); + proc.on("error", () => resolve(1)); + proc.on("close", (code) => resolve(code ?? 1)); + proc.stdin.on("error", () => { + // Ignore EPIPE errors if wl-copy exits early + }); + proc.stdin.write(text); + proc.stdin.end(); }); - proc.stdin.write(text); - proc.stdin.end(); - proc.unref(); - copied = true; + if (wlCopyExit === 0) { + copied = true; + } else if (hasX11Display) { + copyToX11Clipboard(options); + copied = true; + } } catch { if (hasX11Display) { copyToX11Clipboard(options);