tonhowtf/omniget · warning

{}

Error message

{}

What it means

copy_file_linux runs xclip inside spawn_blocking; any error produced inside that closure (spawn failure, wait failure, IO error) is bubbled up and re-wrapped with a bare '{}' format, so the original message passes through unchanged.

Solutions

  1. Read the inner message in the error for the root cause; usually it's the xclip spawn or pipe error.
  2. Ensure an X display/clipboard server is reachable (DISPLAY is set; XWayland running on Wayland).
  3. Install xsel so the fallback clipboard path can be attempted.
  4. Retry — clipboard daemons sometimes recover after a display-manager restart.

Example fix

// before
DISPLAY= omniget copy-file report.pdf  # fails, no display
// after
DISPLAY=:0 omniget copy-file report.pdf
Defensive patterns

Strategy: fallback

Validate before calling

if (!process.env.DISPLAY && process.platform === 'linux') {
  console.warn('DISPLAY is not set; clipboard copy will likely fail');
}

Try / catch

match copy_file_to_clipboard(path).await {
    Err(e) if e.to_string().contains("xclip") => {
        eprintln!("xclip failed: {e}; falling back to xsel or skipping clipboard");
    }
    other => other?,
}

Prevention

When it happens

Trigger: copy_file_to_clipboard on Linux when the xclip blocking task fails for any reason — e.g. clipboard service unavailable, pipe broken after xclip exits early, or the child wait fails.

Common situations: xclip starts but exits immediately because no X clipboard owner is available (headless/Wayland), causing a broken pipe on stdin write; transient display issues.

Related errors


AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12). Data as JSON: /api/errors/5b0eb704766528b2. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/omniget-core/src/core/clipboard.rs:82

            .stdin(std::process::Stdio::piped())
            .spawn()
        {
            Ok(c) => c,
            Err(_) => return Err(anyhow::anyhow!("xclip not found")),
        };
        if let Some(ref mut stdin) = child.stdin {
            use std::io::Write;
            let _ = stdin.write_all(uri_clone.as_bytes());
        }
        let output = child.wait_with_output()?;
        if output.status.success() {
            Ok(true)
        } else {
            Ok(false)
        }
    })
    .await
    .map_err(|e| anyhow::anyhow!("{}", e))?;

    if let Ok(true) = xclip_result {
        tracing::info!("[clipboard] copied file to clipboard (xclip): {}", path);
        return Ok(());
    }

    let uri_clone = uri.clone();
    let xsel_result = tokio::task::spawn_blocking(move || {
        let mut child = match crate::core::process::std_command("xsel")
            .args(["--clipboard", "--input"])
            .stdin(std::process::Stdio::piped())
            .spawn()
        {
            Ok(c) => c,
            Err(_) => return Err(anyhow::anyhow!("xsel not found")),
        };
        if let Some(ref mut stdin) = child.stdin {
            use std::io::Write;

View on GitHub (pinned to 8600b91f42)