sigoden/aichat · error · anyhow::Error

No clipboard available

Error message

No clipboard available

What it means

The public `set_text` delegates to a per-platform `internal::set_text`; on platforms the library does not support for clipboard access (`target_os = "android"` or `target_os = "emscripten"`), the stub unconditionally returns `Err("No clipboard available")`, which the caller wraps with the context "Failed to copy". It signals that clipboard write is simply not implemented for the current target, not that the copy content was invalid.

Solutions

  1. Check the target OS at runtime/compile time and skip or degrade clipboard features on Android/Emscripten.
  2. Use a platform-specific clipboard mechanism on those targets (Android ClipboardManager, browser navigator.clipboard for WASM).
  3. Catch this error and present a non-fatal message, allowing the user to copy manually.
  4. If you own the build, feature-gate the clipboard call behind a capability check.

Example fix

// before
clipboard::set_text(&text).context("Failed to copy")?;
// after
#[cfg(any(target_os = "android", target_os = "emscripten"))]
eprintln!("Clipboard is not supported on this platform; output printed instead");
#[cfg(not(any(target_os = "android", target_os = "emscripten")))]
clipboard::set_text(&text).context("Failed to copy")?;
Defensive patterns

Strategy: fallback

Validate before calling

#[cfg(any(target_os = "android", target_os = "emscripten"))]
const CLIPBOARD_SUPPORTED: bool = false;
#[cfg(not(any(target_os = "android", target_os = "emscripten")))]
const CLIPBOARD_SUPPORTED: bool = true;

Type guard

fn clipboard_supported() -> bool {
    !cfg!(any(target_os = "android", target_os = "emscripten"))
}

Try / catch

match set_text(text) {
    Err(e) if e.to_string().contains("No clipboard available") => {
        println!("{text}"); // let the user copy manually
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling `set_text(text)` while compiled for Android or Emscripten (the `#[cfg(any(target_os = "android", target_os = "emscripten"))]` branch is active).

Common situations: Building a CLI/TUI tool for mobile or WASM targets; running the app in an Android shell or browser-emscripten environment; cross-compiling for an unsupported platform and then invoking copy features.

Understand the failure class

Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.

Related errors


AI-assisted analysis of sigoden/aichat@82976d349a (2026-09-09). Data as JSON: /api/errors/e8b5e15c99c33bab. Report an issue: GitHub.

Appendix: source

Thrown at src/utils/clipboard.rs:43

    /// Attempts to set text to clipboard with OSC52 escape sequence
    /// Works in many modern terminals, including over SSH.
    fn set_text_osc52(text: &str) -> anyhow::Result<()> {
        let encoded = STANDARD.encode(text);
        let seq = format!("\x1b]52;c;{encoded}\x07");
        if let Err(e) = std::io::Write::write_all(&mut std::io::stdout(), seq.as_bytes()) {
            return Err(anyhow::anyhow!("Failed to send OSC52 sequence").context(e));
        }
        if let Err(e) = std::io::Write::flush(&mut std::io::stdout()) {
            return Err(anyhow::anyhow!("Failed to flush OSC52 sequence").context(e));
        }
        Ok(())
    }
}

#[cfg(any(target_os = "android", target_os = "emscripten"))]
mod internal {
    pub fn set_text(_text: &str) -> anyhow::Result<()> {
        Err(anyhow::anyhow!("No clipboard available"))
    }
}

pub fn set_text(text: &str) -> anyhow::Result<()> {
    internal::set_text(text).context("Failed to copy")
}

View on GitHub (pinned to 82976d349a)