a-b-street/abstreet · error · anyhow::Error

{}

Error message

{}

What it means

get_clipboard on native (non-wasm) platforms wraps any failure from creating the clipboard-core ClipboardContext into an anyhow error whose message is just the underlying error's Display output. The library re-raises the clipboard crate's error verbatim because the clipboard crate uses an old nightly-style Error trait that does not convert cleanly to anyhow::Error. Seeing "{}"-style opaque output means the clipboard backend itself failed to initialize.

Solutions

  1. Run the app inside a graphical session (X11 or Wayland) so a clipboard service exists
  2. Enable X forwarding (ssh -X/-Y) or use xauth/xvfb with a clipboard manager when remote
  3. Check that the platform-specific clipboard dependency (x11-clipboard/wayland) is built and its runtime libs are installed
  4. Rephrase: the message is just err.to_string(); match on its text to identify the underlying backend failure

Example fix

// before
let text = get_clipboard().unwrap();
// after
let text = match get_clipboard() {
    Ok(t) => t,
    Err(e) => { eprintln!("clipboard unavailable: {e}"); String::new() }
};
Defensive patterns

Strategy: fallback

Validate before calling

let clipboard_available = !cfg!(target_arch = "wasm32") && std::env::var("DISPLAY").map(|d| !d.is_empty()).unwrap_or(false) || std::env::var("WAYLAND_DISPLAY").is_ok();

Type guard

fn clipboard_likely_available() -> bool {
    std::env::var("WAYLAND_DISPLAY").is_ok() || std::env::var("DISPLAY").map(|d| !d.is_empty()).unwrap_or(false)
}

Try / catch

let text = match get_clipboard() {
    Ok(t) => t,
    Err(e) => { log::warn!("clipboard init failed: {e}"); String::new() }
};

Prevention

When it happens

Trigger: Calling widgetry::tools::get_clipboard() on a native build when ClipboardContext::new() fails, e.g. no X11/Wayland clipboard server available or the clipboard backend cannot connect to the display.

Common situations: Running a headless Linux server or CI container without X11/Wayland; running under SSH without X forwarding; window-manager session not started so no clipboard daemon exists.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13). Data as JSON: /api/errors/d54e53b1f952f224. Report an issue: GitHub.

Appendix: source

Thrown at widgetry/src/tools/mod.rs:121

        {
            error!("Copying to clipboard broke: {}", err);
        }
    }

    #[cfg(target_arch = "wasm32")]
    {
        let _ = x;
    }
}

pub fn get_clipboard() -> Result<String> {
    #[cfg(not(target_arch = "wasm32"))]
    {
        use clipboard::{ClipboardContext, ClipboardProvider};
        // TODO The clipboard crate uses old nightly Errors. Converting to anyhow is weird.
        let mut ctx: ClipboardContext = match ClipboardProvider::new() {
            Ok(ctx) => ctx,
            Err(err) => bail!("{}", err),
        };
        let contents = match ctx.get_contents() {
            Ok(contents) => contents,
            Err(err) => bail!("{}", err),
        };
        Ok(contents)
    }

    #[cfg(target_arch = "wasm32")]
    {
        bail!("Unsupported on web");
    }
}

View on GitHub (pinned to 0964f29315)