gitbutlerapp/gitbutler · error

Failed to parse URL

Error message

Failed to parse URL

What it means

On Linux, revealing a path in the file manager converts the filesystem path to a file:// URL with Url::from_file_path, which only accepts absolute paths. A relative path makes the conversion return Err, surfaced as this error (wrapped with the file-manager context message).

Source

Thrown at crates/but-api/src/open/mod.rs:612

            .with_context(|| format!("Failed to show '{path}' in Finder"))?;
    }

    #[cfg(target_os = "windows")]
    {
        use std::process::Command;
        Command::new("explorer")
            .arg("/select,")
            .arg(&path)
            .status()
            .with_context(|| format!("Failed to show '{path}' in Explorer"))?;
    }

    #[cfg(target_os = "linux")]
    {
        // For directories, open the directory directly
        if std::path::Path::new(&path).is_dir() {
            open_that(
                &Url::from_file_path(&path).map_err(|_| anyhow::anyhow!("Failed to parse URL"))?,
            )
            .with_context(|| format!("Failed to open directory '{path}' in file manager"))?;
        } else {
            // For files, try to open the parent directory
            if let Some(parent) = std::path::Path::new(&path).parent() {
                open_that(
                    &Url::from_file_path(parent)
                        .map_err(|_| anyhow::anyhow!("Failed to parse URL"))?,
                )
                .with_context(|| {
                    format!("Failed to open parent directory of '{path}' in file manager",)
                })?;
            } else {
                open_that(
                    &Url::from_file_path(&path)
                        .map_err(|_| anyhow::anyhow!("Failed to parse URL"))?,
                )
                .with_context(|| format!("Failed to open '{path}' in file manager"))?;

View on GitHub (pinned to 2497b8007a)

Solutions

  1. Join the relative path with the project workdir (or canonicalize it) before calling reveal
  2. Validate that inputs are absolute at the API boundary and reject them early with a clearer message
  3. Reuse the absolute paths already used for git operations

Example fix

// before: repo-relative path
reveal_in_file_manager(relative_path)?;

// after: absolute path from the project workdir
let abs = ctx.workdir()?.join(relative_path);
reveal_in_file_manager(abs.to_string_lossy().as_ref())?;
Defensive patterns

Strategy: validation

Validate before calling

let p = std::path::Path::new(&path);
if !p.is_absolute() {
    let abs = ctx.workdir()?.join(p);
    // use `abs` for the reveal call
}

Type guard

fn path_makes_file_url(p: &std::path::Path) -> bool {
    p.is_absolute()
}

Prevention

When it happens

Trigger: Reveal-in-file-manager invoked with a repo-relative path that was never joined with the project workdir, or a path built by string concatenation that is not absolute.

Common situations: Callers passing repo-internal paths taken from diff output; paths assembled without the workdir prefix; un-canonicalized components like '.' or '..'.

Understand the failure class

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@2497b8007a (2026-08-17). Data as JSON: /api/errors/3f945ad90cf6e5b7. Report an issue: GitHub.