gitbutlerapp/gitbutler · error

Final installation verification failed - attempting to…

Error message

Final installation verification failed - attempting to restore backup

What it means

After the symlink is created, install_app calls validate_installed_binary(&but_symlink) to confirm the installed binary actually runs. If validation fails, the installer warns and rolls back: it removes the new install dir, renames the backup back into place, and re-points (or removes) the symlink. This guards against shipping a broken binary that would leave the user with a non-functional 'but' command.

Solutions

  1. Re-download and re-run the installer to replace a possibly corrupted artifact.
  2. Clear the quarantine attribute (`xattr -dr com.apple.quarantine /Applications/GitButler.app`) and retry if Gatekeeper blocked execution.
  3. Verify you downloaded the artifact matching your CPU architecture (arm64 vs x86_64) or install Rosetta 2.
  4. Check Console.app / security logs for what killed the binary during validation, then address (codesign, AV exclusion).
Defensive patterns

Strategy: retry

Validate before calling

# Validate the artifact before install: run the binary directly.
/usr/sbin/file '/Applications/GitButler.app/Contents/MacOS/gitbutler-tauri'
xattr -l /Applications/GitButler.app | grep -i quarantine

Try / catch

const res = spawnSync(installer, { stdio: 'inherit' });
if (res.status !== 0 && fs.existsSync('/Applications/GitButler.app')) {
  spawnSync('xattr', ['-dr', 'com.apple.quarantine', '/Applications/GitButler.app']);
  // retry the install once
}

Prevention

When it happens

Trigger: download_and_install_app -> install_app on macOS when the freshly installed binary at but_symlink fails validate_installed_binary - e.g. the downloaded .app is corrupted, the binary lacks the executable bit, is unsigned/quarantined and fails to spawn, or the architecture does not match (x86_64 binary on arm64 without Rosetta).

Common situations: Interrupted/partial download producing a corrupt .app; Gatekeeper blocking an unnotarized binary so the spawn check fails; wrong-architecture artifact; antivirus quarantining gitbutler-tauri.

Related errors


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

Appendix: source

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

                    remove_err,
                    install_app_backup.display()
                );
            }
            fs::rename(&install_app_backup, &install_app)?;

            let restored_target = install_app.join("Contents/MacOS/gitbutler-tauri");
            let _ = fs::remove_file(&but_symlink);
            let _ = unix_fs::symlink(&restored_target, &but_symlink);

            bail!("Failed to create symlink: {e}. Previous installation was restored.");
        } else {
            bail!("Failed to create symlink: {e}. No backup available to restore.");
        }
    }

    if !validate_installed_binary(&but_symlink) {
        // Try to restore backup
        warn("Final installation verification failed - attempting to restore backup");
        if install_app_backup.exists() {
            fs::remove_dir_all(&install_app)?;
            fs::rename(&install_app_backup, &install_app)?;

            let restored_target = install_app.join("Contents/MacOS/gitbutler-tauri");
            let _ = fs::remove_file(&but_symlink);
            unix_fs::symlink(&restored_target, &but_symlink)?;

            if validate_installed_binary(&but_symlink) {
                success("Backup was restored successfully");
                bail!("Installation failed but your previous installation was restored");
            } else {
                bail!(
                    "Installation failed and backup restoration also failed - 'but' command may not work"
                );
            }
        } else {
            bail!("Installation failed and no backup available to restore");

View on GitHub (pinned to 58e5313667)