xai-org/grok-build · error

arboard read worker died

Error message

arboard read worker died

What it means

In arboard_read_with_deadline (crates/codegen/xai-grok-shared/src/clipboard.rs:1338), RecvTimeoutError::Disconnected means the read worker thread terminated without sending a result — i.e. it panicked (e.g. inside arboard or the closure) or was killed, rather than timing out. The library reports this as 'arboard read worker died'.

Source

Thrown at crates/codegen/xai-grok-shared/src/clipboard.rs:1338

    /// 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()
                .map_err(anyhow::Error::from)
                .and_then(|mut clipboard| op(&mut clipboard))
        });
        match result {
            Ok(inner) => inner,
            Err(RecvTimeoutError::Timeout) => Err(anyhow::anyhow!("arboard read timed out")),
            Err(RecvTimeoutError::Disconnected) => Err(anyhow::anyhow!("arboard read worker died")),
        }
    }

    fn arboard_get_text() -> anyhow::Result<Option<String>> {
        arboard_read_with_deadline(|clipboard| match clipboard.get_text() {
            Ok(text) if text.is_empty() => Ok(None),
            Ok(text) => Ok(Some(text)),
            Err(arboard::Error::ContentNotAvailable) => Ok(None),
            Err(err) => Err(err.into()),
        })
    }

    #[cfg(target_os = "linux")]
    fn arboard_get_primary_text() -> anyhow::Result<Option<String>> {
        use arboard::{GetExtLinux, LinuxClipboardKind};
        arboard_read_with_deadline(|clipboard| {
            match clipboard
                .get()

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Retry the read once — a transient panic after a display-server restart often clears.
  2. Update the arboard dependency to the latest patch version for platform panic fixes.
  3. Capture the worker panic message (panic hook/log) to identify the underlying platform error.
  4. Fall back to OS CLI clipboard tools if worker deaths recur.
Defensive patterns

Strategy: retry

Try / catch

let mut attempts = 0;
loop {
    match arboard_get_text() {
        Err(e) if e.to_string() == "arboard read worker died" && attempts < 2 => { attempts += 1; continue; }
        other => break other,
    }
}

Prevention

When it happens

Trigger: arboard_get_text / arboard_get_primary_text / arboard_get_image / get_file_urls when the worker thread panics during Clipboard::new() or the op closure — e.g. an arboard platform bug or an unexpected Wayland/X11 protocol abort.

Common situations: Arboard version-specific panics on certain compositors; OOM kills of the worker thread; platform clipboard API misbehaving after display server restarts.

Related errors


AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31). Data as JSON: /api/errors/9ddfd75e62d4a48b. Report an issue: GitHub.