block / block/buzz

Desktop: ensure_cli_symlink retargets ~/.local/bin/buzz at the AppImage extract under /tmp

Open
#6,110 0 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.