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
- Re-download and re-extract the release archive — a truncated download is the most common cause
- Check which binary is named in the message and confirm it exists in the release artifact (unzip -l the asset)
- If a release genuinely lacks the binary, use a previous known-good release version and report the packaging regression
- 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
- Verify download size/checksum before extraction
- List archive contents (unzip -l) to confirm all expected binaries ship in the asset
- Pin to a known-good release version if a new asset is incomplete
- Extract to a fresh directory so prior partial extractions cannot mask missing files
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
- Extracted app bundle does not contain expected directory…
- Downloaded file does not appear to be a valid gzip archive
- A 'but' binary already exists at
- Aborting due to empty branch name
- Aborting due to empty
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)