Hmbown/CodeWhale · warning

OSC 52 clipboard fallback requires a terminal

Error message

OSC 52 clipboard fallback requires a terminal

What it means

The OSC 52 fallback can only write to a terminal, and enqueue_terminal_write detected that stdout is not a TTY while also not being inside tmux (the tmux path routes through load-buffer instead of stdout). This guard prevents writing clipboard escape sequences into a pipe or file.

Source

Thrown at crates/tui/src/tui/clipboard.rs:479

            #[cfg(target_os = "windows")]
            if write_text_with_set_clipboard(text).is_ok() {
                return Ok(());
            }

            self.enqueue_terminal_write(text)
                .map_err(|err| anyhow::anyhow!("Clipboard unavailable: {err}"))
        }
    }

    #[cfg(not(test))]
    fn enqueue_terminal_write(&mut self, text: &str) -> Result<()> {
        if !self.terminal_context.in_tmux {
            if text.len() > OSC52_MAX_BYTES {
                bail!("selection is too large for OSC 52 clipboard fallback");
            }
            if !io::stdout().is_terminal() {
                bail!("OSC 52 clipboard fallback requires a terminal");
            }
        }

        if self.terminal_writer.is_none() {
            self.terminal_writer = Some(TerminalClipboardWriter::spawn()?);
        }
        self.terminal_writer
            .as_ref()
            .expect("terminal clipboard writer initialized")
            .enqueue(text, self.terminal_context.in_tmux)
    }

    /// Return one completed background terminal clipboard write, if available.
    ///
    /// Successes are intentionally quiet because callers already show their
    /// normal copy receipt. Failures are drained by the event loop and replace
    /// that optimistic receipt with an actionable error.
    pub(crate) fn poll_write_completion(&self) -> Option<TerminalClipboardWriteCompletion> {

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Run the TUI with stdout attached to a real terminal (no piping/redirect) when clipboard fallback is needed.
  2. Prefer tmux: inside a tmux session the copy uses load-buffer -w and does not require stdout to be a TTY.
  3. Install a system clipboard utility so the OSC 52 fallback is never selected.
Defensive patterns

Strategy: validation

Validate before calling

use std::io::IsTerminal;

fn osc52_write_possible(in_tmux: bool) -> bool {
    in_tmux || std::io::stdout().is_terminal()
}

Prevention

When it happens

Trigger: Invoking the copy action when Codewhale's stdout is piped, redirected, or detached: running under a wrapper that captures output, in tests, or from a daemonized context without tmux.

Common situations: Running the TUI through output-capturing wrappers, script(1), or CI; launching from a launcher that redirects stdout; clipboard request arriving after the terminal was detached.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20). Data as JSON: /api/errors/170c52500b6f03bb. Report an issue: GitHub.