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
- Stop the old daemon (`atuin daemon stop` or kill the process) and let the new binary start one.
- Set `daemon.autostart = true` in ~/.config/atuin/config.toml so the client restarts the daemon automatically.
- 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
- Keep daemon.autostart = true so version skews self-heal.
- After upgrading atuin, always restart the daemon.
- Install only one atuin build to avoid version skew.
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
- daemon autostart is incompatible with…
- . Enable `daemon.autostart = true` or restart the daemon…
- `atuin history tail` requires Atuin to be built with the…
- Config key must be non-empty and must not contain whitespace
- Could not build config
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)