{"record":{"id":"5cb3708f7311cb2a","repo":"atuinsh/atuin","slug":"message","errorCode":null,"errorMessage":"{message}","messagePattern":"\\{message\\}","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/atuin/src/command/client/daemon.rs","lineNumber":425,"sourceCode":"    let _ = wait_until_ready(settings, timeout).await?;\n\n    drop(startup_lock);\n    Ok(())\n}\n\nasync fn restart_daemon(settings: &Settings) -> Result<HistoryClient> {\n    ensure_daemon_running(settings).await?;\n    connect_client(settings).await\n}\n\nfn ensure_reply_compatible(settings: &Settings, version: &str, protocol: u32) -> Result<()> {\n    if daemon_matches_expected(version, protocol) {\n        return Ok(());\n    }\n\n    let message = daemon_mismatch_message(version, protocol);\n    if settings.daemon.autostart {\n        bail!(\"{message}\");\n    }\n\n    bail!(\"{message}. Enable `daemon.autostart = true` or restart the daemon manually\");\n}\n\n/// Acquire a [`HistoryClient`] connected to a daemon we expect to understand us, probing over the\n/// wire-stable Status RPC first and restarting the daemon if it is absent or version/protocol\n/// skewed.\n///\n/// TODO(markovejnovic): This is egregious slop, but not worse than the original solution. I want to\n///                      remove this in a future PR: <https://github.com/atuinsh/atuin/pull/4002>\npub async fn ready_client(settings: &Settings) -> Result<HistoryClient> {\n    match probe(settings).await {\n        Probe::Ready(client) => return Ok(client),\n        Probe::NeedsRestart(reason) if !settings.daemon.autostart => {\n            bail!(\"{reason}. Enable `daemon.autostart = true` or restart the daemon manually\");\n        }\n        Probe::Unreachable(err) if is_legacy_daemon_error(&err) => {","sourceCodeStart":407,"sourceCodeEnd":443,"githubUrl":"https://github.com/atuinsh/atuin/blob/900007c48045867e7f44b0f9bc55ad9dbe99ee0d/crates/atuin/src/command/client/daemon.rs#L407-L443","documentation":"Before using a running daemon, the CLI checks that the daemon's reported version and protocol are compatible with the client (`ensure_reply_compatible`). On mismatch it builds a descriptive message: if autostart is enabled the daemon can simply be restarted transparently, so it bails with the plain message (the caller `try_with_restart` will handle restart); otherwise it appends guidance to enable autostart or restart manually.","triggerScenarios":"Client and daemon binaries of different atuin versions are mixed (e.g. after upgrading the CLI but the old daemon process is still running), or the daemon speaks a different protocol version than the client expects.","commonSituations":"Upgrading atuin (package manager, cargo install) while a long-lived daemon keeps running the old build; switching between system and self-built binaries; running the CLI in a container against a host daemon.","solutions":["Kill the running daemon (`pkill atuin` / stop the systemd unit) and let the new binary start it.","Enable `daemon.autostart = true` in config so the CLI restarts mismatched daemons automatically.","Re-run the command after restarting so both sides match versions.","Ensure only one installation of atuin is on PATH (`which -a atuin`) and upgrade all of them consistently."],"exampleFix":"# before\natuin stats  # daemon is old version -> version/protocol mismatch bail\n# after\npkill atuin && atuin stats   # restart daemon with the upgraded client","handlingStrategy":"retry","validationCode":"# compare running daemon version with the CLI\natuin version 2>/dev/null; pgrep -a atuin   # stale daemon process?","typeGuard":null,"tryCatchPattern":"match client_cmd() {\n    Err(e) if e.to_string().contains(\"Enable `daemon.autostart`\") || e.to_string().contains(\"protocol\") => {\n        stop_daemon();\n        client_cmd()  // retry; autostart spawns a matching daemon\n    }\n    other => other,\n}","preventionTips":["Restart the daemon after every atuin upgrade.","Enable daemon.autostart so mismatched daemons are replaced automatically.","Keep a single atuin installation on PATH.","In containers, run client and daemon from the same image/version."],"tags":["daemon","versioning","protocol"],"backgroundTag":"version-incompatible","analyzedSha":"900007c48045867e7f44b0f9bc55ad9dbe99ee0d","analyzedAt":"2026-09-19T12:52:51.491Z","contentChangedAt":"2026-09-19T12:52:51.491Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}