{"record":{"id":"af12540b5b908470","repo":"gitbutlerapp/gitbutler","slug":"new-installation-verification-failed-but-binar","errorCode":null,"errorMessage":"New installation verification failed - 'but' binary cannot run (may be corrupted or blocked by macOS)","messagePattern":"New installation verification failed - 'but' binary cannot run \\(may be corrupted or blocked by macOS\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-installer/src/install_macos.rs","lineNumber":179,"sourceCode":"    }\n\n    // Create temporary symlink to test the new installation\n    let new_app_macos_dir = install_app_new.join(\"Contents/MacOS/gitbutler-tauri\");\n    let _ = fs::remove_file(&but_new);\n\n    unix_fs::symlink(&new_app_macos_dir, &but_new)?;\n\n    // Verify the new installation works\n    let verify_status = Command::new(&but_new)\n        .arg(\"--version\")\n        .stdout(Stdio::null())\n        .stderr(Stdio::null())\n        .status();\n\n    if !verify_status.map(|s| s.success()).unwrap_or(false) {\n        fs::remove_dir_all(&install_app_new)?;\n        fs::remove_file(&but_new)?;\n        bail!(\n            \"New installation verification failed - 'but' binary cannot run (may be corrupted or blocked by macOS)\"\n        );\n    }\n\n    // New installation is valid - now do the atomic swap\n    info(\"Swapping new installation into place...\");\n\n    // Helper to clean up stale installation artifacts\n    let cleanup_artifacts = || {\n        let _ = fs::remove_dir_all(&install_app_new);\n        let _ = fs::remove_file(&but_new);\n    };\n\n    // Backup existing installation if it exists\n    let had_backup = install_app.exists();\n    if had_backup && let Err(e) = fs::rename(&install_app, &install_app_backup) {\n        // Failed to backup - clean up artifacts before failing\n        cleanup_artifacts();","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but-installer/src/install_macos.rs#L161-L197","documentation":"macOS path: before any swap, install_macos stages the extracted .app, creates a candidate 'but' symlink to its gitbutler-tauri binary, and runs 'but --version'. If that fails, the staged new install is deleted and the installer bails - the existing installation is untouched at this point. The parenthetical names the two usual causes on macOS: a corrupted binary, or Gatekeeper blocking an unnotarized/quarantined one.","triggerScenarios":"The staged binary exits non-zero or is killed: Gatekeeper kills an unnotarized nightly (SIGKILL before main), the downloaded bundle is corrupted, an x86_64 artifact runs on arm64 without Rosetta, or the extraction lost the executable bit.","commonSituations":"Nightly channel on managed Macs; corporate MDM enforcing stricter Gatekeeper; missing Rosetta 2 on Apple Silicon; CDN object corruption that still passed signature check.","solutions":["Run the extracted binary directly ( staging path or the downloaded .app: open the app once and check Privacy & Security for a block notice, then 'Allow Anyway'","Retry the install to rule out a corrupted download","On arm64 with an x86_64 artifact: softwareupdate --install-rosetta","Prefer the notarized release channel over nightly on locked-down Macs"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// After manual download/extract, verify the binary executes before installing\nlet status = std::process::Command::new(&extracted_but)\n    .arg(\"--version\")\n    .stdout(std::process::Stdio::null())\n    .stderr(std::process::Stdio::null())\n    .status();\nanyhow::ensure!(status.is_ok_and(|s| s.success()), \"binary blocked or corrupted\");","typeGuard":null,"tryCatchPattern":"match but_installer::run_installation_with_version(request, false) {\n    Err(e) if e.to_string().contains(\"New installation verification failed\") => {\n        // check Gatekeeper/quarantine and Rosetta, then retry once\n        clear_quarantine_and_retry()?;\n    }\n    result => result,\n}","preventionTips":["Allow GitButler releases in Gatekeeper/MDM policy before scripted installs","Keep Rosetta installed on arm64 for x86_64 artifacts","Prefer the notarized release channel on locked-down Macs"],"tags":["rust","macos","gatekeeper","binary-validation","quarantine","but-installer"],"backgroundTag":"installation-verification-failed","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}