xai-org/grok-build · error
arboard unavailable
Error message
arboard unavailable
What it means
arboard_lease (crates/codegen/xai-grok-shared/src/clipboard.rs:1313) creates an arboard Clipboard on a worker thread; when Clipboard::new() fails or does not complete, the lease is None and this error is returned. It means no in-process clipboard backend could be initialized — usually no accessible display/selection server.
Source
Thrown at crates/codegen/xai-grok-shared/src/clipboard.rs:1313
}
match spawn_with_deadline(
"clipboard-init",
DISPLAY_CONN_WAIT,
arboard::Clipboard::new,
) {
Ok(Ok(clipboard)) => Some(parking_lot::Mutex::new(clipboard)),
Ok(Err(e)) => {
tracing::debug!("arboard Clipboard::new failed: {e}");
None
}
Err(e) => {
tracing::debug!("arboard Clipboard::new did not complete: {e}");
None
}
}
})
.as_ref()
.ok_or_else(|| anyhow::anyhow!("arboard unavailable"))
}
/// Deadline for in-process arboard reads. The Wayland data-control read has
/// no internal timeout and blocks forever on a hung selection owner (the
/// X11 path has a 4 s budget), so reads run on a worker thread that is
/// abandoned on expiry. The worker's `Clipboard` instance leaks with it;
/// harmless while the lease keeps the shared backend alive.
const ARBOARD_READ_WAIT: std::time::Duration = std::time::Duration::from_secs(2);
fn arboard_read_with_deadline<T: Send + 'static>(
op: impl FnOnce(&mut arboard::Clipboard) -> anyhow::Result<T> + Send + 'static,
) -> anyhow::Result<T> {
use std::sync::mpsc::RecvTimeoutError;
if arboard_wayland_bypassed() {
anyhow::bail!("arboard leg disabled (GROK_CLIPBOARD_NO_DATA_CONTROL)");
}
let result = spawn_with_deadline("clipboard-read", ARBOARD_READ_WAIT, move || {
arboard::Clipboard::new()View on GitHub (pinned to bc7f02eddd)
Solutions
- Set DISPLAY (X11) or WAYLAND_DISPLAY correctly for the running process.
- Run inside a graphical session or use x/wayland forwarding for SSH.
- Install the missing Wayland/X11 clipboard protocol support or fall back to CLI tools (xclip/wl-copy/pbcopy).
- If init is timing out, check for a hung compositor/selection owner.
Example fix
// before
clipboard.arboard_set_text("hi")?; // fails headless
// after
if std::env::var_os("WAYLAND_DISPLAY").or_else(|| std::env::var_os("DISPLAY")).is_some() {
clipboard.arboard_set_text("hi")?;
} else {
eprintln!("no display; clipboard skipped");
} Defensive patterns
Strategy: fallback
Validate before calling
fn has_display() -> bool {
std::env::var_os("WAYLAND_DISPLAY").is_some()
|| std::env::var_os("DISPLAY").is_some()
} Try / catch
match arboard_set_text(text) {
Err(e) if e.to_string() == "arboard unavailable" => cli_set_text_fallback(text),
other => other,
} Prevention
- Check DISPLAY/WAYLAND_DISPLAY before clipboard calls in headless environments.
- Degrade gracefully: clipboard features should be optional in services/CI.
- Log the underlying Clipboard::new error (it is already debug-logged) to diagnose compositor issues.
When it happens
Trigger: arboard_set_text on a headless machine (no X11/Wayland display), with DISPLAY/WAYLAND_DISPLAY unset or pointing at a dead server, or when the clipboard init timed out and returned None.
Common situations: SSH sessions without X forwarding, CI containers, Wayland compositors without the data-control protocol, Windows services in session 0.
Related errors
- no clipboard backend available
- arboard leg disabled (GROK_CLIPBOARD_NO_DATA_CONTROL)
- {bin} exited with status {status}
- no CLI tool supports image clipboard writes
- arboard read timed out
AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31).
Data as JSON: /api/errors/ff65d5aa0487ebdc.
Report an issue: GitHub.