Desktop: ensure_cli_symlink retargets ~/.local/bin/buzz at the AppImage extract under /tmp
- Dominant language
- Rust
- Stars
- 32.7k
- Forks
- 4.3k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 253
Description
**Describe the bug**
On Linux, every desktop boot runs `ensure_cli_symlink` (`desktop/src-tauri/src/managed_agents/nest.rs`). That function deletes any existing symlink at `~/.local/bin/buzz` and creates a new one to the bundled CLI next to `current_exe()`.
An AppImage sets `current_exe()` under `/tmp/appimage_extracted_*/usr/bin`. `/tmp` is tmpfs on many distros. After a reboot the target is gone. Anything that calls `buzz` by name then fails: no binary, no error from desktop, agents and timers just stop posting.
The function already leaves a regular file alone. That is the documented escape hatch for a user-compiled binary. A hardlink of a durable CLI at `~/.local/lib/buzz-/buzz` therefore survives boot. A symlink does not.
This is a different failure from #3471. That issue is the installer GUI wrapper script. This one is desktop overwriting a working CLI symlink on every start.
**Steps to reproduce**
1. Install `Buzz_0.5.14_amd64.AppImage` (or any current Linux AppImage).
2. Extract `usr/bin/buzz` to a durable path, e.g. `~/.local/lib/buzz-0.5.14/buzz`.
3. `ln -sfn ~/.local/lib/buzz-0.5.14/buzz ~/.local/bin/buzz`
4. Confirm `buzz --help` prints `Buzz CLI`.
5. Open the AppImage.
6. `readlink -f ~/.local/bin/buzz`
**Expected behavior**
`~/.local/bin/buzz` still names a durable CLI. The function skips the write when `current_exe()` is under `/tmp`, or when `~/.local/bin/buzz` already exists.
**Actual behavior**
The symlink now points at `/tmp/appimage_extracted_/usr/bin/buzz`. Observed on Fedora with desktop-v0.5.14 at 16-08-2026 18:09 and 17-08-2026 09:31. The two binaries were byte-identical. The path is what breaks.
**Version and platform**
- Buzz version: 0.5.14 (`Buzz_0.5.14_amd64.AppImage`)
- OS: Fedora Linux
- The same function is on `main` (`desktop/src-tauri/src/managed_agents/nest.rs`). Tests already cover "do not clobber a regular file".
**Logs / additional context**
```rust
// On every boot: replaces any existing symlink unconditionally (the `buzz` /
// `buzz-dev` name is our namespace), creates a new one if absent, and leaves
// regular files alone to avoid clobbering a user-compiled binary.
```
A tight fix is: return early when `exe_parent` is under `/tmp` (or under `appimage_extracted_`). Alternatively, skip the replace when the existing symlink target exists and is not this process's bundled CLI.
Workaround that survives boot today: replace the symlink with a hardlink (`ln`, no `-s`) of the durable CLI. The regular-file branch leaves it alone.
Duplicates searched: none for `ensure_cli_symlink` + `/tmp`. Closest open issue is #3471 (installer wrapper named `buzz`).
Contributor guide
Assessment
This issue has not been assessed yet.