{"record":{"id":"2770059f00144b18","repo":"gitbutlerapp/gitbutler","slug":"failed-to-move-new-installation-into-place-resto","errorCode":null,"errorMessage":"Failed to move new installation into place - restoring backup","messagePattern":"Failed to move new installation into place - restoring backup","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-installer/src/install_macos.rs","lineNumber":208,"sourceCode":"        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();\n        return Err(e.into());\n    }\n\n    // Move new installation into place with rollback on failure\n    if let Err(e) = fs::rename(&install_app_new, &install_app) {\n        // Clean up stale artifacts before handling the error\n        cleanup_artifacts();\n\n        // Critical failure - restore backup if we created one\n        if had_backup && install_app_backup.exists() {\n            warn(\"Failed to move new installation into place - restoring backup\");\n            if let Err(restore_err) = fs::rename(&install_app_backup, &install_app) {\n                bail!(\n                    \"Failed to install new version: {}. Also failed to restore backup: {}. Your app may be at {}\",\n                    e,\n                    restore_err,\n                    install_app_backup.display()\n                );\n            }\n            bail!(\n                \"Failed to install new version: {e}. Previous installation restored successfully.\"\n            );\n        }\n        // No backup to restore, just fail\n        bail!(\"Failed to move new installation into place: {e}\");\n    }\n\n    // Update the symlink to point to the new installation\n    let final_target = install_app.join(\"Contents/MacOS/gitbutler-tauri\");","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but-installer/src/install_macos.rs#L190-L226","documentation":"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.","triggerScenarios":"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.","commonSituations":"Applications directory owned by another admin account; disk-full machines; the app moved across volumes before updating; security software locking .app bundles during updates.","solutions":["Fix permissions or ownership of the Applications folder (or reinstall under the user's ~/Applications) and re-run the installer","Free disk space, then update again","If the bail names a backup path, manually move that app back into place","If both renames failed and no app remains, download and install fresh"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"fn dir_is_writable(dir: &std::path::Path) -> bool {\n    let probe = dir.join(\".but-write-probe\");\n    std::fs::write(&probe, b\"1\").is_ok() && std::fs::remove_file(&probe).is_ok()\n}\n// call before staging: dir_is_writable(&home_dir.join(\"Applications\"))","typeGuard":null,"tryCatchPattern":"if let Err(e) = fs::rename(&install_app_new, &install_app) {\n    cleanup_artifacts();\n    if let Err(restore_err) = fs::rename(&install_app_backup, &install_app) {\n        bail!(\"install failed: {e}; restore failed: {restore_err}; old app at {}\",\n              install_app_backup.display());\n    }\n    bail!(\"Installation failed: {e}. Previous installation restored.\");\n}","preventionTips":["Verify the destination directory is writable before staging a new bundle","Keep old and new bundles on the same volume","Quit the running app before updating","Delete the backup only after the final rename is verified"],"tags":["rust","macos","installer","rename","rollback","filesystem"],"backgroundTag":"install-rollback-failed","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}