gitbutlerapp/gitbutler · error

Missing required binary

Error message

Missing required binary: {binary}

What it means

verify_app_structure requires specific binaries (gitbutler-git-askpass and gitbutler-tauri) inside Contents/MacOS of the extracted .app bundle. If one of these expected executables is absent, the bundle is considered incomplete and installation is aborted with this error naming the missing binary.

Solutions

  1. Re-download and re-extract the release archive — a truncated download is the most common cause
  2. Check which binary is named in the message and confirm it exists in the release artifact (unzip -l the asset)
  3. If a release genuinely lacks the binary, use a previous known-good release version and report the packaging regression
  4. Ensure the extraction tool preserves all files (no permission/case issues that silently skip entries)
Defensive patterns

Strategy: validation

Validate before calling

fn required_binaries_present(app_dir: &std::path::Path) -> bool {
    ["gitbutler-git-askpass", "gitbutler-tauri"]
        .iter()
        .all(|b| app_dir.join("Contents/MacOS").join(b).exists())
}

Try / catch

if let Err(e) = download_and_install_app(...).await {
    if e.to_string().starts_with("Missing required binary") {
        // re-download asset or pin to a known-good release
    }
}

Prevention

When it happens

Trigger: download_and_install_app extracts the archive, Contents/MacOS exists, but binaries_dir.join(binary) does not exist for one of ["gitbutler-git-askpass", "gitbutler-tauri"] — bail!("Missing required binary: {binary}").

Common situations: Truncated or corrupted download dropping files, packaging pipeline that stopped shipping one of the binaries (version change), archive extraction skipping files (permissions, case sensitivity), wrong artifact for the platform where one binary is absent.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18). Data as JSON: /api/errors/28e67ae3d2eeeb4c. Report an issue: GitHub.

Appendix: source

Thrown at crates/but-installer/src/install_macos.rs:349

    }

    app_dir.ok_or_else(|| anyhow!("No .app bundle found in extracted archive"))
}

pub(crate) fn verify_app_structure(app_dir: &Path) -> Result<()> {
    let binaries_dir = app_dir.join("Contents/MacOS");
    if !binaries_dir.is_dir() {
        bail!(
            "Extracted app bundle does not contain expected directory structure (Contents/MacOS)"
        );
    }

    let required_binaries = ["gitbutler-git-askpass", "gitbutler-tauri"];

    for binary in &required_binaries {
        let binary_path = binaries_dir.join(binary);
        if !binary_path.exists() {
            bail!("Missing required binary: {binary}");
        }
    }

    Ok(())
}

fn validate_tarball(path: &Path) -> Result<()> {
    // Check if file is not empty
    let metadata = fs::metadata(path).context("Failed to read tarball metadata")?;
    if metadata.len() == 0 {
        bail!("Downloaded file is empty");
    }

    // Check for gzip magic bytes (1f 8b)
    if !is_gzip_file(path)? {
        bail!("Downloaded file does not appear to be a valid gzip archive");
    }

View on GitHub (pinned to 58e5313667)