gitbutlerapp/gitbutler · error

Failed to move new installation into place - restoring backu

Error message

Failed to move new installation into place - restoring backup

What it means

The macOS updater stages a new app bundle (install_app_new), optionally backs up the current one, then fs::rename()s the staged bundle over the real location in ~/Applications. If that rename fails, this warn announces rollback: artifacts are cleaned and the backup is renamed back into place. Failure of both renames bails with a combined message naming where the old app was left.

Source

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

        let _ = fs::remove_file(&but_new);
    };

    // 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");

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Fix permissions or ownership of the Applications folder (or reinstall under the user's ~/Applications) and re-run the installer
  2. Free disk space, then update again
  3. If the bail names a backup path, manually move that app back into place
  4. If both renames failed and no app remains, download and install fresh
Defensive patterns

Strategy: fallback

Validate before calling

fn dir_is_writable(dir: &std::path::Path) -> bool {
    let probe = dir.join(".but-write-probe");
    std::fs::write(&probe, b"1").is_ok() && std::fs::remove_file(&probe).is_ok()
}
// call before staging: dir_is_writable(&home_dir.join("Applications"))

Try / catch

if let Err(e) = fs::rename(&install_app_new, &install_app) {
    cleanup_artifacts();
    if let Err(restore_err) = fs::rename(&install_app_backup, &install_app) {
        bail!("install failed: {e}; restore failed: {restore_err}; old app at {}",
              install_app_backup.display());
    }
    bail!("Installation failed: {e}. Previous installation restored.");
}

Prevention

When it happens

Trigger: fs::rename(&install_app_new, &install_app) fails at crates/but-installer/src/install_macos.rs:208 — ~/Applications not writable by the user, disk full, backup or staged bundle on a different volume, or another process holding a lock on the bundle.

Common situations: Applications directory owned by another admin account; disk-full machines; the app moved across volumes before updating; security software locking .app bundles during updates.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/2770059f00144b18. Report an issue: GitHub.