atuinsh/atuin · error

. Enable `daemon.autostart = true` or restart the daemon…

Error message

{message}. Enable `daemon.autostart = true` or restart the daemon manually

What it means

The client could not talk to a daemon whose version/protocol matches its own; `daemon_mismatch_message` describes the skew. Because `daemon.autostart` is disabled, the client cannot restart the daemon itself and tells you the two supported remedies. This is raised by `ensure_reply_compatible` during the Status RPC probe in `try_with_restart`.

Solutions

  1. Stop the old daemon (`atuin daemon stop` or kill the process) and let the new binary start one.
  2. Set `daemon.autostart = true` in ~/.config/atuin/config.toml so the client restarts the daemon automatically.
  3. Ensure only one atuin version is installed and on PATH.

Example fix

// before (config.toml)
[daemon]
autostart = false

// after
[daemon]
autostart = true
Defensive patterns

Strategy: validation

Validate before calling

// before relying on daemon-backed commands:
let cfg = std::fs::read_to_string("~/.config/atuin/config.toml")?;
if !cfg.contains("autostart = true") {
    eprintln!("daemon.autostart disabled: restart the daemon manually after upgrading atuin");
}

Prevention

When it happens

Trigger: Running a client command (e.g. history writes via the daemon) while a running daemon reports a version or wire-protocol mismatch, and `settings.daemon.autostart` is false.

Common situations: Upgrading the atuin binary while an old daemon process is still running; running two different atuin versions (e.g. a package-manager build vs a cargo-installed build); having autostart explicitly disabled in config.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of atuinsh/atuin@900007c480 (2026-09-19). Data as JSON: /api/errors/f12dd1aed130f1e6. Report an issue: GitHub.

Appendix: source

Thrown at crates/atuin/src/command/client/daemon.rs:428

    Ok(())
}

async fn restart_daemon(settings: &Settings) -> Result<HistoryClient> {
    ensure_daemon_running(settings).await?;
    connect_client(settings).await
}

fn ensure_reply_compatible(settings: &Settings, version: &str, protocol: u32) -> Result<()> {
    if daemon_matches_expected(version, protocol) {
        return Ok(());
    }

    let message = daemon_mismatch_message(version, protocol);
    if settings.daemon.autostart {
        bail!("{message}");
    }

    bail!("{message}. Enable `daemon.autostart = true` or restart the daemon manually");
}

/// Acquire a [`HistoryClient`] connected to a daemon we expect to understand us, probing over the
/// wire-stable Status RPC first and restarting the daemon if it is absent or version/protocol
/// skewed.
///
/// TODO(markovejnovic): This is egregious slop, but not worse than the original solution. I want to
///                      remove this in a future PR: <https://github.com/atuinsh/atuin/pull/4002>
pub async fn ready_client(settings: &Settings) -> Result<HistoryClient> {
    match probe(settings).await {
        Probe::Ready(client) => return Ok(client),
        Probe::NeedsRestart(reason) if !settings.daemon.autostart => {
            bail!("{reason}. Enable `daemon.autostart = true` or restart the daemon manually");
        }
        Probe::Unreachable(err) if is_legacy_daemon_error(&err) => {
            return Err(err.wrap_err(LEGACY_DAEMON_RESTART_MESSAGE));
        }
        Probe::Unreachable(err) if !settings.daemon.autostart => return Err(err),

View on GitHub (pinned to 900007c480)