{"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/58e5313667b857ef39a730e380af31816a7b1768/crates/but-installer/src/install_macos.rs#L161-L197","documentation":"The macOS installer runs the newly installed `but` binary once (with stdio discarded) to prove it executes before swapping it into place. If the verification process exits non-zero or fails to spawn, the new .app contents are deleted and this error is raised — commonly because Gatekeeper quarantined the unsigned/unnotarized binary or the download was corrupted.","triggerScenarios":"macOS Gatekeeper/Translocation blocks the freshly downloaded binary (com.apple.quarantine xattr); the binary was corrupted in transit; the download is for the wrong architecture (x86_64 on Apple Silicon without Rosetta); exec permission missing.","commonSituations":"Installing on a locked-down corporate Mac with strict Gatekeeper policy; network middleboxes corrupting large downloads; freshly released macOS versions blocking notarization-less binaries; running on Apple Silicon without Rosetta 2 installed.","solutions":["Check the error output of running `but_new` manually at the staging path for the real reason.","Remove quarantine if appropriate: `xattr -dr com.apple.quarantine <path to new app/binary>`, then retry.","Verify you downloaded the correct architecture artifact (aarch64 vs x86_64) and install Rosetta 2 (`softwareupdate --install-rosetta`) if needed.","Re-download — corrupted artifacts fail exec; retry the install to get a fresh copy.","Check System Settings → Privacy & Security for a blocked-app notice and Allow it, then retry."],"exampleFix":"// before\nbut upgrade   # \"New installation verification failed...\"\n// after\nxattr -dr com.apple.quarantine /path/to/new/but\nsoftwareupdate --install-rosetta --agree-to-license   # Intel binary on Apple Silicon\nbut upgrade","handlingStrategy":"validation","validationCode":"use std::process::Command;\nfn new_binary_runs(path: &std::path::Path) -> bool {\n    Command::new(path).arg(\"--version\")\n        .stdout(Stdio::null()).stderr(Stdio::null())\n        .status().map(|s| s.success()).unwrap_or(false)\n}\n// also check quarantine before install:\nlet quarantined = Command::new(\"xattr\").args([\"-p\", \"com.apple.quarantine\"])\n    .arg(path).output().map(|o| o.status.success()).unwrap_or(false);","typeGuard":null,"tryCatchPattern":"if !new_binary_runs(&but_new) {\n    let _ = Command::new(\"xattr\").args([\"-dr\", \"com.apple.quarantine\"]).arg(&install_app_new).status();\n    if !new_binary_runs(&but_new) {\n        anyhow::bail!(\"new but binary cannot execute even after removing quarantine\");\n    }\n}","preventionTips":["Strip com.apple.quarantine from downloaded artifacts before executing them.","Verify architecture (aarch64 vs x86_64) matches the machine; install Rosetta 2 for Intel binaries on Apple Silicon.","Test-execute the binary at the staging location before the atomic swap.","Keep Gatekeeper/notarization status of releases in mind when automating installs on locked-down Macs."],"tags":["macos","installation","gatekeeper","verification"],"backgroundTag":"unexpected-response-shape","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"}