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
- Check the target OS at runtime/compile time and skip or degrade clipboard features on Android/Emscripten.
- Use a platform-specific clipboard mechanism on those targets (Android ClipboardManager, browser navigator.clipboard for WASM).
- Catch this error and present a non-fatal message, allowing the user to copy manually.
- 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
- Compile-time gate clipboard features on target OS with cfg!.
- Provide a print-to-stdout fallback for unsupported targets.
- Document platform support for clipboard features in the README.
- Test WASM/mobile builds in CI so unsupported code paths surface early.
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)