{"record":{"id":"06c1ae3b797b9b51","repo":"gitbutlerapp/gitbutler","slug":"installation-failed-and-backup-restoration-also-fa-06c1ae","errorCode":null,"errorMessage":"Installation failed and backup restoration also failed - 'but' command may not work","messagePattern":"Installation failed and backup restoration also failed - 'but' command may not work","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/but-installer/src/install_macos.rs","lineNumber":273,"sourceCode":"        }\n    }\n\n    if !validate_installed_binary(&but_symlink) {\n        // Try to restore backup\n        warn(\"Final installation verification failed - attempting to restore backup\");\n        if install_app_backup.exists() {\n            fs::remove_dir_all(&install_app)?;\n            fs::rename(&install_app_backup, &install_app)?;\n\n            let restored_target = install_app.join(\"Contents/MacOS/gitbutler-tauri\");\n            let _ = fs::remove_file(&but_symlink);\n            unix_fs::symlink(&restored_target, &but_symlink)?;\n\n            if validate_installed_binary(&but_symlink) {\n                success(\"Backup was restored successfully\");\n                bail!(\"Installation failed but your previous installation was restored\");\n            } else {\n                bail!(\n                    \"Installation failed and backup restoration also failed - 'but' command may not work\"\n                );\n            }\n        } else {\n            bail!(\"Installation failed and no backup available to restore\");\n        }\n    }\n\n    success(&format!(\n        \"{} installed successfully\",\n        app_basename.to_string_lossy()\n    ));\n    // Remove backup on success\n    let _ = fs::remove_dir_all(&install_app_backup);\n\n    success(\"GitButler CLI (but) installed successfully\");\n\n    Ok(())","sourceCodeStart":255,"sourceCodeEnd":291,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but-installer/src/install_macos.rs#L255-L291","documentation":"Thrown when the macOS install of the new app bundle fails AND restoring the backup also fails: after copying the backup back, validate_installed_binary(&but_symlink) reports the restored binary is not usable, leaving the `but` command potentially broken. This is the worst-case path of install_app's failure handling.","triggerScenarios":"install_app fails mid-install, a backup exists and is restored over the target, but validate_installed_binary(&but_symlink) fails (restored binary missing, not executable, or symlink points at a broken path) — the else branch bails with this message.","commonSituations":"Backup itself was corrupted or incomplete, interrupted previous update left a partial backup, antivirus/quarantine stripping the executable bit, symlink target removed between restore and validation, full disk during restore copy.","solutions":["Check that the symlink target exists and is executable: `ls -l $(which but)` and `file` the target; recreate the symlink if dangling","Run the installer again to force a fresh download and clean backup/restore cycle","Manually reinstall: download the .app release, copy it over the broken bundle, and re-link `but` to Contents/MacOS/gitbutler-tauri","Check disk space and quarantine attributes (`xattr -d com.apple.quarantine`) on the restored bundle"],"exampleFix":"// before\nif validate_installed_binary(&but_symlink) { ... } else { bail!(\"Installation failed and backup restoration also failed - 'but' command may not work\"); }\n// after (shell recovery)\nln -sf \"/Applications/GitButler.app/Contents/MacOS/gitbutler-tauri\" ~/.local/bin/but && but --version","handlingStrategy":"retry","validationCode":"fn backup_binary_valid(backup_dir: &std::path::Path) -> bool {\n    let bin = backup_dir.join(\"Contents/MacOS/gitbutler-tauri\");\n    bin.exists() && bin.is_file()\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = download_and_install_app(...).await {\n    if e.to_string().contains(\"backup restoration also failed\") {\n        // manual recovery: re-download release and reinstall\n    }\n}","preventionTips":["Never interrupt an update mid-copy; let backup/restore complete","Verify backups are complete after creation before deleting the old bundle","Watch for quarantine attributes stripping the executable bit on restored binaries","Monitor disk space during install and restore"],"tags":["macos","installer","corrupt-install","broken-binary"],"backgroundTag":"app-install-failed-backup-restore-failed","analyzedSha":"58e5313667b857ef39a730e380af31816a7b1768","analyzedAt":"2026-09-18T06:50:32.052Z","contentChangedAt":"2026-09-18T06:50:32.052Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}