atuinsh/atuin · error

`atuin update` is only available when atuin was installed vi

Error message

`atuin update` is only available when atuin was installed via the standalone installer (https://setup.atuin.sh).
If you installed atuin with a package manager (brew, nix, pacman, cargo, ...), please update it there instead.

What it means

`atuin update` delegates to the standalone installer's self-update machinery, which relies on an install receipt written by the setup.atuin.sh shell/powershell installers. If no receipt can be loaded, atuin assumes it was installed by a package manager (brew, nix, pacman, cargo, ...) and refuses to self-update so as not to fight that manager.

Source

Thrown at crates/atuin/src/command/client/update.rs:31

    /// Update (or roll back) to a specific version, e.g. "18.9.0" or
    /// "18.9.0-nightly.1", instead of the channel's latest release
    #[arg(long, conflicts_with = "check")]
    version: Option<String>,
}

impl Cmd {
    #[instrument(level = "trace", skip_all, err)]
    pub async fn run(self, settings: &Settings) -> Result<()> {
        let current = env!("CARGO_PKG_VERSION");

        let mut updater = AxoUpdater::new_for("atuin");
        updater.disable_installer_output();

        // The install receipt is written by the shell/powershell installers.
        // No receipt means atuin came from a package manager, which should
        // stay in charge of upgrades.
        if updater.load_receipt().is_err() {
            bail!(
                "`atuin update` is only available when atuin was installed via the standalone installer (https://setup.atuin.sh).\n\
                 If you installed atuin with a package manager (brew, nix, pacman, cargo, ...), please update it there instead."
            );
        }

        // The receipt records the version the installer wrote; trust the
        // binary itself in case it was replaced by other means.
        let _ = updater.set_current_version(current.parse()?);

        if !updater.check_receipt_is_for_this_executable()? {
            let current_exe = std::env::current_exe()?;
            let receipt_prefix = updater.install_prefix_root()?;
            bail!(
                "This atuin binary ({}) is not the one the standalone installer installed to {}. \
                 Are multiple copies of atuin installed?",
                current_exe.display(),
                receipt_prefix,
            );

View on GitHub (pinned to c0c717ab04)

Solutions

  1. Update via your package manager instead: `brew upgrade atuin`, `pacman -Syu atuin`, `cargo install atuin`, etc.
  2. If you want self-update, install via the standalone installer: `curl https://setup.atuin.sh | sh` (replaces the package-managed binary with one it owns).
  3. Check your install origin (`which atuin`) to confirm which update path applies.

Example fix

// before
atuin update   # cargo-installed binary, no receipt
// after
cargo install atuin   # update through the same channel it was installed from
Defensive patterns

Strategy: validation

Validate before calling

# shell
# detect package-manager installs and route update accordingly
if command -v brew >/dev/null && brew list atuin >/dev/null 2>&1; then
  brew upgrade atuin
else
  atuin update
fi

Try / catch

if ! atuin update 2>&1 | grep -q 'standalone installer'; then :; fi
# fallback to the channel it was installed from (brew/nix/pacman/cargo)

Prevention

When it happens

Trigger: Running `atuin update` when atuin was installed via a package manager or built from source, so `updater.load_receipt()` returns Err (no receipt file present).

Common situations: Homebrew/Nix/APT/pacman installs, `cargo install atuin` builds, CI images, or a receipt lost after moving home directories.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of atuinsh/atuin@c0c717ab04 (2026-09-12). Data as JSON: /api/errors/5dbfa4c6bb8bad2b. Report an issue: GitHub.