gitbutlerapp/gitbutler · error · anyhow::Error

Errors occurred: {cmd_errors:?}

Error message

Errors occurred: {cmd_errors:?}

What it means

After the scheme check, open_that (crates/but-api/src/open/mod.rs:98-131) runs every opener command the `open` crate derives for the platform and pushes a 'Failed to execute command' entry whenever cmd.status() itself errors (the process could not be spawned at all, distinct from a non-zero exit). If every candidate failed, the aggregated bail at line 129 fires listing all failed commands.

Source

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

            "LD_LIBRARY_PATH",
            "PATH",
            "PERLLIB",
            "PYTHONHOME",
            "PYTHONPATH",
            "QT_PLUGIN_PATH",
            "XDG_DATA_DIRS",
        ]);

        cmd.envs(cleaned_vars);
        cmd.current_dir(env::temp_dir());
        if cmd.status().is_ok() {
            return Ok(());
        } else {
            cmd_errors.push(anyhow::anyhow!("Failed to execute command {cmd:?}"));
        }
    }
    if !cmd_errors.is_empty() {
        bail!("Errors occurred: {cmd_errors:?}");
    }
    Ok(())
}

/// Opens supported editor URLs directly inside WSL.
///
/// The normal URL opener can fail to route `vscode://file/...`-style URLs back
/// to Linux editor CLIs when GitButler runs in WSL, so this attempts a direct
/// invocation first. Returns `true` only when a supported editor command was
/// executed successfully; unsupported URLs and failed launches fall back to the
/// generic opener.
fn open_editor_url_as_command_invocation_on_wsl(target_url: &Url) -> bool {
    use std::process::Command;

    if !is_wsl() {
        return false;
    }

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Install an opener on Linux: xdg-utils (xdg-open) or glib (gio)
  2. Check the app's PATH: launch it from a shell to compare, or fix the .desktop launcher's environment
  3. Bypass the generic opener and invoke the specific target program (browser, editor CLI) directly
  4. On WSL, prefer editor schemes that route through the direct CLI invocation path

Example fix

# before: no opener installed on a minimal distro
open https://example.com  # error: Errors occurred: [Failed to execute command ...]

# after: install xdg-utils
sudo apt install xdg-utils   # Debian/Ubuntu
sudo pacman -S xorg-xdg-utils  # Arch
Defensive patterns

Strategy: fallback

Validate before calling

import { access } from 'fs/promises';

async function hasOpener(bin: string): Promise<boolean> {
  for (const dir of process.env.PATH!.split(':')) {
    try {
      await access(`${dir}/${bin}`);
      return true;
    } catch { /* keep checking */ }
  }
  return false;
}
const genericOpenerOk = await hasOpener('xdg-open') || await hasOpener('gio');

Try / catch

try {
  await openThat(url);
} catch (e) {
  if (String(e).startsWith('Errors occurred')) {
    // fallback: launch a concrete program yourself
    await execFile('firefox', [url.toString()]);
  } else throw e;
}

Prevention

When it happens

Trigger: Minimal or headless Linux where no xdg-open/gio/kde-open exists; a broken PATH inside the app environment (launched from a launcher rather than a shell); WSL without an opener where an unsupported editor URL fell back to the generic opener.

Common situations: GitButler packaged as an AppImage/sandboxed desktop app on bare WMs (i3, sway without xdg-utils); CI containers; PATH mangled by env cleaning or a wrapper script.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/54cf683d4c2211c4. Report an issue: GitHub.