Hmbown/CodeWhale · warning · anyhow::Error
Clipboard unavailable: {err}
Error message
Clipboard unavailable: {err} What it means
Thrown by ClipboardHandler::write_text when the detected terminal context forces ClipboardWriteOrder::TerminalClientOnly (an SSH session with no forwarded X11/Wayland display, or CODEWHALE_SSH_CLIPBOARD=terminal). On this path no native clipboard helper is tried; the write goes straight to enqueue_terminal_write (tmux load-buffer or OSC 52), and any failure there is wrapped as 'Clipboard unavailable: {err}'. Typical inner errors: selection larger than OSC52_MAX_BYTES (100 KiB) outside tmux, stdout not a terminal, terminal writer spawn/queue failure, or tmux errors.
Source
Thrown at crates/tui/src/tui/clipboard.rs:435
pub fn write_text(&mut self, text: &str) -> Result<()> {
#[cfg(test)]
{
if let Some(writer) = self.terminal_writer.as_ref() {
return writer.enqueue(text, self.terminal_context.in_tmux);
}
if self.fail_text_writes {
bail!("test clipboard unavailable");
}
self.written_text.push(text.to_string());
Ok(())
}
#[cfg(not(test))]
{
if self.terminal_context.write_order() == ClipboardWriteOrder::TerminalClientOnly {
return self
.enqueue_terminal_write(text)
.map_err(|err| anyhow::anyhow!("Clipboard unavailable: {err}"));
}
#[cfg(all(target_os = "linux", not(target_env = "ohos")))]
if write_text_with_wlcopy(text).is_ok() {
return Ok(());
}
#[cfg(any(
target_os = "macos",
target_os = "windows",
all(target_os = "linux", not(target_env = "ohos"))
))]
{
self.ensure_clipboard();
if let Some(clipboard) = self.clipboard.as_mut()
&& clipboard.set_text(text.to_string()).is_ok()
{
return Ok(());View on GitHub (pinned to 0c42157ee5)
Solutions
- Copy a smaller selection (under 100 KiB), or run inside tmux where the OSC 52 size cap does not apply
- Use an OSC 52-capable terminal (iTerm2, kitty, WezTerm, Alacritty; tmux needs set-clipboard on) and keep stdout attached to the TTY
- Forward a display (ssh -X/-Y) or set CODEWHALE_SSH_CLIPBOARD=graphical with a live display so the native clipboard path is used instead
- Wait for the queued terminal write to drain before copying again; avoid back-to-back large copies
Example fix
# before ssh remote-host # no -X; copy a 500 KiB selection # -> Clipboard unavailable: selection is too large for OSC 52 clipboard fallback # after ssh -X remote-host # forwarded display -> native clipboard path # or run inside tmux on the remote host and keep selections under 100 KiB
Defensive patterns
Strategy: fallback
Validate before calling
// Rust - pre-flight the terminal-client copy path
use std::io::IsTerminal;
const OSC52_MAX_BYTES: usize = 100 * 1024;
fn terminal_copy_ok(text: &str, in_tmux: bool) -> bool {
if !in_tmux {
if text.len() > OSC52_MAX_BYTES { return false; }
if !std::io::stdout().is_terminal() { return false; }
}
true
} Try / catch
match clipboard.write_text(text) {
Ok(()) => show_copy_receipt(),
Err(err) => show_warning(format!("Clipboard unavailable: {err:#}")),
} // copy is best-effort: never abort the turn on clipboard failure Prevention
- Keep copyable selections under 100 KiB when relying on OSC 52
- Prefer tmux or an OSC 52-capable terminal for remote sessions
- Know the env contract: SSH_TTY set with empty DISPLAY/WAYLAND_DISPLAY forces the terminal-client-only path
When it happens
Trigger: write_text() while SSH_CLIENT/SSH_CONNECTION/SSH_TTY is set with no usable DISPLAY/WAYLAND_DISPLAY, and then: (a) not in tmux and text.len() > 100*1024, (b) io::stdout() is not a terminal (piped/redirected), (c) the TerminalClipboardWriter thread failed to spawn or stopped, (d) another terminal write still occupies the single-slot queue ('another terminal clipboard write is still queued'), or (e) inside tmux the `tmux load-buffer -w -` child fails to spawn or exits non-zero.
Common situations: SSH into a remote host without X11 forwarding and copying a large transcript; TUI stdout piped or redirected; local terminal with OSC 52 disabled or unsupported (many defaults); rapid consecutive large copies overrunning the one-slot write queue.
Related errors
- selection is too large for OSC 52 clipboard fallback
- OSC 52 clipboard fallback requires a terminal
- tmux load-buffer -w exited with {}
- tmux load-buffer -w exited with {}: {detail}
- Failed to run tmux load-buffer -w: {e}
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/e7cf80c47c61b80b.
Report an issue: GitHub.