gitbutlerapp/gitbutler · critical
Failed to install new version: {}. Also failed to restore ba
Error message
Failed to install new version: {}. Also failed to restore backup: {}. Your app may be at {} What it means
Critical macOS rollback failure: fs::rename of the staged new .app into the install location failed, and the follow-up rename restoring the backup failed too. The message embeds the original rename error, the restore error, and the backup path where the previous app still sits. The install location may now be empty or partial, so manual recovery is expected.
Source
Thrown at crates/but-installer/src/install_macos.rs:210
// Backup existing installation if it exists
let had_backup = install_app.exists();
if had_backup && let Err(e) = fs::rename(&install_app, &install_app_backup) {
// Failed to backup - clean up artifacts before failing
cleanup_artifacts();
return Err(e.into());
}
// Move new installation into place with rollback on failure
if let Err(e) = fs::rename(&install_app_new, &install_app) {
// Clean up stale artifacts before handling the error
cleanup_artifacts();
// Critical failure - restore backup if we created one
if had_backup && install_app_backup.exists() {
warn("Failed to move new installation into place - restoring backup");
if let Err(restore_err) = fs::rename(&install_app_backup, &install_app) {
bail!(
"Failed to install new version: {}. Also failed to restore backup: {}. Your app may be at {}",
e,
restore_err,
install_app_backup.display()
);
}
bail!(
"Failed to install new version: {e}. Previous installation restored successfully."
);
}
// No backup to restore, just fail
bail!("Failed to move new installation into place: {e}");
}
// Update the symlink to point to the new installation
let final_target = install_app.join("Contents/MacOS/gitbutler-tauri");
let _ = fs::remove_file(&but_symlink);
View on GitHub (pinned to caf1f223d3)
Solutions
- Quit GitButler completely (Cmd-Q) and retry the install
- Manually restore from the printed backup path: mv '<backup path from the message>' /Applications/GitButler.app
- Free disk space and fix permissions on the install dir, then rerun but-installer
- If the backup path no longer exists, do a fresh install and treat the previous app as lost
Example fix
# recovery for the state after this error mv "$(path printed after 'Your app may be at')" /Applications/GitButler.app ln -sf /Applications/GitButler.app/Contents/MacOS/gitbutler-tauri ~/.local/bin/but
Defensive patterns
Strategy: try-catch
Validate before calling
// Before an update: the app must not be running, and space must be available
let running = std::process::Command::new("pgrep")
.arg("-x").arg("gitbutler-tauri")
.stdout(std::process::Stdio::null())
.status().is_ok_and(|s| s.success());
anyhow::ensure!(!running, "GitButler is running; quit it before updating"); Try / catch
if let Err(e) = but_installer::run_installation_with_version(request, false) {
let msg = e.to_string();
if msg.contains("Also failed to restore backup") {
// recover manually from the path printed after "Your app may be at"
let backup = msg.rsplit("Your app may be at ").next().unwrap_or_default();
recover_app_from_backup(std::path::Path::new(backup.trim()))?;
}
return Err(e);
} Prevention
- Quit GitButler before running updates
- Keep roughly 2x app-bundle size free on the install volume
- Run the installer as the user who owns the install directory
When it happens
Trigger: The swap rename fails because the target app bundle is running (macOS locks bundle executables), the install dir is not writable, or the disk is full - and the backup restore then fails for the same or a compounding reason (permissions, disk full, SIP-protected path).
Common situations: Updating while GitButler desktop app is open; non-admin user installing into /Applications; disk pressure during the double-size swap window.
Related errors
- Failed to move new installation into place: {e}
- Failed to install new version: {e}. Previous installation re
- Failed to create symlink and failed to remove new installati
- Installation failed and backup restoration also failed - 'bu
- Extracted app bundle does not contain expected directory str
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/8994d9e55d4c6bf5.
Report an issue: GitHub.