gitbutlerapp/gitbutler · warning
Found existing 'but' symlink pointing to: {existing_target_s
Error message
Found existing 'but' symlink pointing to: {existing_target_str} What it means
Warning from the macOS installer when ~/.local/bin/but is a symlink whose target is neither a Nightly build (target string contains 'Nightly') nor a GitButler.app release (contains '/GitButler.app/'). The installer classifies it as a custom, non-GitButler symlink (previous_channel is None) and warns because the final swap step will overwrite it with a symlink to the new app bundle. It is purely informational; the install proceeds.
Source
Thrown at crates/but-installer/src/install_macos.rs:153
info(&format!(
"Your original 'but' has been saved to: {}",
but_backup.display()
));
} else if but_symlink.is_symlink() {
let existing_target = fs::read_link(&but_symlink)?;
let existing_target_str = existing_target.to_string_lossy();
// Detect channel switching
let previous_channel = if existing_target_str.contains("Nightly") {
Some(Channel::Nightly)
} else if existing_target_str.contains("/GitButler.app/") {
Some(Channel::Release)
} else {
None
};
if previous_channel.is_none() {
warn(&format!(
"Found existing 'but' symlink pointing to: {existing_target_str}"
));
warn("This will be replaced with GitButler's 'but' command");
info(
"Note: Your custom symlink setup will be overwritten. The original target is not a GitButler installation.",
);
}
}
// Create temporary symlink to test the new installation
let new_app_macos_dir = install_app_new.join("Contents/MacOS/gitbutler-tauri");
let _ = fs::remove_file(&but_new);
unix_fs::symlink(&new_app_macos_dir, &but_new)?;
// Verify the new installation works
let verify_status = Command::new(&but_new)
.arg("--version")View on GitHub (pinned to caf1f223d3)
Solutions
- Note the target printed in the warning, then let the installer overwrite it; re-create your custom link afterwards if it pointed at something you still need (ln -sfn /your/target ~/.local/bin/but)
- Preempt the warning by removing the symlink before installing: rm ~/.local/bin/but
- If the target was a cargo-installed CLI you still want, keep it reachable via its original path (e.g. ~/.cargo/bin/but is already on PATH)
- Confirm after install: readlink ~/.local/bin/but should show .../GitButler.app/Contents/MacOS/gitbutler-tauri
Example fix
# before readlink ~/.local/bin/but /Users/me/.cargo/bin/but # custom target, will be overwritten # after install - restore your custom link under another name if needed ln -sfn /Users/me/.cargo/bin/but ~/.local/bin/but-custom
Defensive patterns
Strategy: validation
Validate before calling
# Before installing, see what the symlink points at: target=$(readlink ~/.local/bin/but 2>/dev/null) if [ -n "$target" ] && ! [[ "$target" == *GitButler.app* ]] && ! [[ "$target" == *Nightly* ]]; then echo "custom symlink -> $target will be replaced by the installer" echo "$target" > ~/but-symlink.bak # persist it yourself fi
Prevention
- Record 'readlink ~/.local/bin/but' before every install; the installer only logs the target, it does not save it
- Keep personal symlinks under different names (but-custom) so GitButler's 'but' never collides
- After install, verify 'readlink ~/.local/bin/but' points into GitButler.app
When it happens
Trigger: Existing symlink created by the user, e.g. ln -s ~/.cargo/bin/but ~/.local/bin/but, a self-compiled build in ~/builds/but, or a symlink to an unrelated tool that also happens to be named 'but'. Channel detection at install_macos.rs:144-150 fails both the 'Nightly' and '/GitButler.app/' substring checks, so previous_channel is None and the warn fires at line 153.
Common situations: Dotfile-managed symlinks; switching from a source-build CLI to the desktop-app-installed one; tool name collision with another 'but' binary; stale symlink left behind after moving a self-built app.
Related errors
- This will be replaced with GitButler's 'but' command
- A 'but' binary already exists at {} (not a symlink)
- Moving it to {} to preserve your existing file
- Failed to create symlink: {e} - attempting to restore backup
- Refusing to install symlink onto existing non-symlink at '{U
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/3944b3810ae61066.
Report an issue: GitHub.