gitbutlerapp/gitbutler · error
Installation failed but your previous installation was resto
Error message
Installation failed but your previous installation was restored
What it means
Final macOS validation: after the swap, 'but --version' through the new symlink failed. The installer removed the new app, restored the backup, recreated the symlink, re-validated, and the restored version passes - so it bails with this message. Your previous installation is intact and working; the new artifact was rejected at run time.
Source
Thrown at crates/but-installer/src/install_macos.rs:271
} 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");
}
}
success(&format!(
"{} installed successfully",
app_basename.to_string_lossy()
));
// Remove backup on success
let _ = fs::remove_dir_all(&install_app_backup);
success("GitButler CLI (but) installed successfully");View on GitHub (pinned to caf1f223d3)
Solutions
- Keep using the restored old version - no repair is strictly needed
- Check System Settings > Privacy & Security for a blocked-binary notice for the new version; allow it or switch to the notarized release channel
- Install Rosetta on Apple Silicon if the new artifact is x86_64: softwareupdate --install-rosetta
- Retry later in case of transient corruption
Defensive patterns
Strategy: fallback
Validate before calling
// Pre-flight the staged binary the way the installer will (but --version)
let status = std::process::Command::new(&staged_but)
.arg("--version")
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::null())
.status();
anyhow::ensure!(status.is_ok_and(|s| s.success()),
"new binary blocked (Gatekeeper/Rosetta); skipping update"); Try / catch
match but_installer::run_installation_with_version(request, false) {
Err(e) if e.to_string().contains("previous installation was restored") => {
// rollback already succeeded; old version is live. Keep it and report.
log::warn!("update rejected at validation; staying on previous version");
}
result => result,
} Prevention
- Prefer the notarized release channel over nightly on managed Macs
- Keep Rosetta installed on Apple Silicon
- Treat single-shot validation failure as transient: retry before pinning blame
When it happens
Trigger: The new app's binary does not execute while the old one does: Gatekeeper quarantine blocking the freshly downloaded (e.g. unnotarized nightly) bundle, a corrupted download, or an x86_64 build on arm64 without Rosetta.
Common situations: Nightly channel on Gatekeeper-strict macOS; missing Rosetta; transient CDN corruption; MDM policy changes applied between versions.
Related errors
- New installation verification failed - 'but' binary cannot r
- Installation failed and backup restoration also failed - 'bu
- Installation failed and no backup available to restore
- Failed to install new version: {e}. Previous installation re
- Failed to create symlink: {e}. Previous installation was res
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/314308e432bae77b.
Report an issue: GitHub.