{"record":{"id":"ceee142d9a7ee34b","repo":"gitbutlerapp/gitbutler","slug":"failed-to-create-symlink-e-no-backup-available","errorCode":null,"errorMessage":"Failed to create symlink: {e}. No backup available to restore.","messagePattern":"Failed to create symlink: (.+?)\\. No backup available to restore\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-installer/src/install_macos.rs","lineNumber":254,"sourceCode":"            \"Failed to create symlink: {e} - attempting to restore backup\"\n        ));\n        if install_app_backup.exists() {\n            if let Err(remove_err) = fs::remove_dir_all(&install_app) {\n                bail!(\n                    \"Failed to create symlink and failed to remove new installation during rollback: {}. Backup at: {}\",\n                    remove_err,\n                    install_app_backup.display()\n                );\n            }\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            let _ = unix_fs::symlink(&restored_target, &but_symlink);\n\n            bail!(\"Failed to create symlink: {e}. Previous installation was restored.\");\n        } else {\n            bail!(\"Failed to create symlink: {e}. No backup available to restore.\");\n        }\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 {","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but-installer/src/install_macos.rs#L236-L272","documentation":"First macOS install: creating the 'but' symlink failed and no backup exists to restore. The new app may be installed, but the CLI link is missing. Same failure class as the restored variant - the link path is unwritable or occupied - except there is nothing to fall back to.","triggerScenarios":"unix_fs::symlink fails because ~/.local/bin cannot be created or written (parent not writable, read-only home), a non-file object already occupies the but path, or the link target directory is missing.","commonSituations":"Fresh machines with corporate read-only or root-owned home mounts; stray 'but' directory; PATH bin dir never created.","solutions":["mkdir -p ~/.local/bin and ensure it is user-writable, then re-run the installer","Or create the link manually: ln -s /Applications/GitButler.app/Contents/MacOS/gitbutler-tauri ~/.local/bin/but","Remove any directory occupying the but path first","Verify ~/.local/bin is on PATH afterwards"],"exampleFix":"# manual completion of a first install that failed here\nmkdir -p ~/.local/bin\nln -s /Applications/GitButler.app/Contents/MacOS/gitbutler-tauri ~/.local/bin/but","handlingStrategy":"validation","validationCode":"// Pre-create and probe the symlink dir before a first install\nlet bin_dir = home.join(\".local/bin\");\nstd::fs::create_dir_all(&bin_dir)?; // fails clearly if HOME is not writable\nlet probe = bin_dir.join(\".write-probe\");\nstd::fs::write(&probe, b\"\")?;\nstd::fs::remove_file(&probe)?;\nanyhow::ensure!(!bin_dir.join(\"but\").is_dir(), \"a directory occupies the 'but' path\");","typeGuard":null,"tryCatchPattern":"if let Err(e) = but_installer::run_installation_with_version(request, false) {\n    let msg = e.to_string();\n    if msg.contains(\"Failed to create symlink\") && msg.contains(\"No backup available\") {\n        // complete the first install by hand\n        let _ = std::fs::remove_file(home.join(\".local/bin/but\"));\n        std::os::unix::fs::symlink(\n            install_app.join(\"Contents/MacOS/gitbutler-tauri\"),\n            home.join(\".local/bin/but\"))?;\n    }\n    return Err(e);\n}","preventionTips":["Ensure ~/.local/bin exists and is writable before first install","Remove any object occupying the 'but' link path","Confirm ~/.local/bin is on PATH after install"],"tags":["rust","macos","symlink","first-install","permissions","but-installer"],"backgroundTag":"symlink-creation-failed","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}