{"record":{"id":"28e67ae3d2eeeb4c","repo":"gitbutlerapp/gitbutler","slug":"missing-required-binary-binary","errorCode":null,"errorMessage":"Missing required binary: {binary}","messagePattern":"Missing required binary: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-installer/src/install_macos.rs","lineNumber":349,"sourceCode":"    }\n\n    app_dir.ok_or_else(|| anyhow!(\"No .app bundle found in extracted archive\"))\n}\n\npub(crate) fn verify_app_structure(app_dir: &Path) -> Result<()> {\n    let binaries_dir = app_dir.join(\"Contents/MacOS\");\n    if !binaries_dir.is_dir() {\n        bail!(\n            \"Extracted app bundle does not contain expected directory structure (Contents/MacOS)\"\n        );\n    }\n\n    let required_binaries = [\"gitbutler-git-askpass\", \"gitbutler-tauri\"];\n\n    for binary in &required_binaries {\n        let binary_path = binaries_dir.join(binary);\n        if !binary_path.exists() {\n            bail!(\"Missing required binary: {binary}\");\n        }\n    }\n\n    Ok(())\n}\n\nfn validate_tarball(path: &Path) -> Result<()> {\n    // Check if file is not empty\n    let metadata = fs::metadata(path).context(\"Failed to read tarball metadata\")?;\n    if metadata.len() == 0 {\n        bail!(\"Downloaded file is empty\");\n    }\n\n    // Check for gzip magic bytes (1f 8b)\n    if !is_gzip_file(path)? {\n        bail!(\"Downloaded file does not appear to be a valid gzip archive\");\n    }\n","sourceCodeStart":331,"sourceCodeEnd":367,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but-installer/src/install_macos.rs#L331-L367","documentation":"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.","triggerScenarios":"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}\").","commonSituations":"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.","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)"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"fn required_binaries_present(app_dir: &std::path::Path) -> bool {\n    [\"gitbutler-git-askpass\", \"gitbutler-tauri\"]\n        .iter()\n        .all(|b| app_dir.join(\"Contents/MacOS\").join(b).exists())\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = download_and_install_app(...).await {\n    if e.to_string().starts_with(\"Missing required binary\") {\n        // re-download asset or pin to a known-good release\n    }\n}","preventionTips":["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"],"tags":["macos","app-bundle","missing-binary","validation"],"backgroundTag":"file-not-found","analyzedSha":"58e5313667b857ef39a730e380af31816a7b1768","analyzedAt":"2026-09-18T06:50:32.052Z","contentChangedAt":"2026-09-18T06:50:32.052Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}