xai-org/grok-build · error
failed to run {bin}: {e}
Error message
failed to run {bin}: {e} What it means
The CLI clipboard read helper at crates/codegen/xai-grok-shared/src/clipboard.rs:1835 spawns a read tool (e.g. wl-paste/xclip) with piped stdout and maps a spawn failure to this error. stdout is drained on a worker thread so a hung tool can be killed at the deadline; a non-zero exit is reported separately.
Source
Thrown at crates/codegen/xai-grok-shared/src/clipboard.rs:1835
/// Run a CLI tool and capture its stdout, bounded by `deadline`
/// (`CLI_PROBE_WAIT` for read-backs, `CLI_READ_WAIT` for content reads).
#[cfg(target_os = "linux")]
fn run_capture_out_with_status(
argv: &[&str],
deadline: std::time::Duration,
) -> anyhow::Result<(std::process::ExitStatus, Vec<u8>)> {
let (bin, args) = argv.split_first().expect("argv non-empty");
let mut cmd = Command::new(bin);
cmd.args(args)
.stdin(Stdio::null())
.stdout(Stdio::piped())
.stderr(Stdio::null());
xai_grok_tools::util::detach_std_command(&mut cmd);
#[allow(clippy::disallowed_methods)] // short-lived clipboard helper, waited on below
let mut child = cmd
.spawn()
.map_err(|e| anyhow::anyhow!("failed to run {bin}: {e}"))?;
// Drain stdout on a worker so the deadline wait can kill a hung tool
// without deadlocking on a full pipe; the kill EOFs the pipe and the
// reader exits on its own.
let mut stdout = child.stdout.take().expect("stdout piped");
let reader = std::thread::spawn(move || {
use std::io::Read;
let mut buf = Vec::new();
let _ = stdout.read_to_end(&mut buf);
buf
});
let status = super::wait_with_deadline(&mut child, deadline)?;
let stdout = reader.join().unwrap_or_default();
Ok((status, stdout))
}
/// Capture CLI stdout. Non-zero exit → empty bytes (typed MIME absent), not Err.
/// Spawn/timeout failures still return Err. Prefer this over
/// [`run_capture_out_checked`] for content reads where a missing type isView on GitHub (pinned to bc7f02eddd)
Solutions
- Install the matching reader (`wl-clipboard` or `xclip`) and verify with `which <bin>`.
- Select the binary based on the active display server.
- Correct PATH in the invoking environment.
- Use arboard-based reads as a fallback.
Defensive patterns
Strategy: validation
Validate before calling
fn pick_read_bin() -> Option<&'static str> {
let wayland = std::env::var_os("WAYLAND_DISPLAY").is_some();
let (preferred, alt) = if wayland { ("wl-paste", "xclip") } else { ("xclip", "wl-paste") };
[preferred, alt].into_iter().find(|b| which(b).is_some())
} Prevention
- Ensure the reader binary matching your display server is installed.
- Probe read-tool availability before relying on CLI clipboard reads.
- Fall back to arboard reads when no CLI tool is present.
When it happens
Trigger: Reading the clipboard via the CLI path when the binary is missing from PATH, not executable, or the exec fails — same conditions as the write-side spawn error but on the read path.
Common situations: Fresh Linux installs without xclip/wl-paste; containers; running the X11 tool under Wayland or vice versa.
Related errors
- failed to spawn {bin}: {e}
- no clipboard backend available
- arboard leg disabled (GROK_CLIPBOARD_NO_DATA_CONTROL)
- {bin} exited with status {status}
- no CLI tool supports image clipboard writes
AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31).
Data as JSON: /api/errors/709089c7d8e0143e.
Report an issue: GitHub.