nikivdev/code · error

pbcopy exited with status {}

Error message

pbcopy exited with status {}

What it means

The clipboard helper on macOS spawns `pbcopy` (via the platform-specific cfg branch), writes the text to its stdin, and checks the child's exit status. If pbcopy terminates with a nonzero status, the code bails with the exit status. This indicates the copy-to-clipboard operation genuinely failed even though pbcopy was found and launched.

Source

Thrown at src/ai.rs:14167

/// Copy text to system clipboard.
fn copy_to_clipboard(text: &str) -> Result<()> {
    if std::env::var("FLOW_NO_CLIPBOARD").is_ok() {
        return Ok(());
    }
    #[cfg(target_os = "macos")]
    {
        let mut child = Command::new("pbcopy")
            .stdin(Stdio::piped())
            .spawn()
            .context("failed to spawn pbcopy")?;

        if let Some(stdin) = child.stdin.as_mut() {
            stdin.write_all(text.as_bytes())?;
        }

        let status = child.wait()?;
        if !status.success() {
            bail!("pbcopy exited with status {}", status);
        }
    }

    #[cfg(target_os = "linux")]
    {
        // Try xclip first, then xsel
        let result = Command::new("xclip")
            .arg("-selection")
            .arg("clipboard")
            .stdin(Stdio::piped())
            .spawn();

        let mut child = match result {
            Ok(c) => c,
            Err(_) => Command::new("xsel")
                .arg("--clipboard")
                .arg("--input")
                .stdin(Stdio::piped())

View on GitHub (pinned to a747e741ae)

Solutions

  1. Run the command from a local GUI session (Terminal.app/iTerm) rather than SSH, or use `pbcopy` with reattach-to-user-namespace workarounds where applicable
  2. Test manually: `echo test | pbcopy && pbpaste` to confirm the pasteboard works outside the tool
  3. Check the printed status for signal-exit codes (e.g. 9/137) pointing at OOM or kill policies, and free resources/adjust limits
  4. As a workaround, print the text to stdout and copy it manually

Example fix

// before (SSH session)
$ myapp ai copy last
Error: pbcopy exited with status 1
// after (local GUI shell)
$ echo test | pbcopy && pbpaste
test
$ myapp ai copy last   # succeeds
Defensive patterns

Strategy: fallback

Validate before calling

use std::process::Command;
fn pbcopy_works() -> bool {
    Command::new("pbcopy").stdin(std::process::Stdio::piped()).spawn().is_ok()
}
if !pbcopy_works() { eprintln!("clipboard unavailable; printing to stdout instead"); }

Try / catch

match copy_to_clipboard(text) {
    Err(e) if e.to_string().starts_with("pbcopy exited") => {
        eprintln!("clipboard failed ({e}); falling back to stdout");
        println!("{text}");
    }
    Err(e) => return Err(e),
    Ok(()) => {}
}

Prevention

When it happens

Trigger: pbcopy fails to access the macOS pasteboard — e.g. running over SSH without a GUI session, in a headless context, or in sandboxes that deny pasteboard access; pbcopy killed by a signal (status reported as signal exit).

Common situations: SSH into a Mac and run the copy command — no Aqua session owns the pasteboard; running inside restrictive CI or container contexts; system clipboard daemon issues after long uptimes.

Related errors


AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01). Data as JSON: /api/errors/e0bd06ae4efe58cf. Report an issue: GitHub.