Skip to content

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

Description

@OmerFarukOruc

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-<ver>/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_<hash>/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

// 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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions