atuinsh/atuin · error

`atuin history tail` requires Atuin to be built with the…

Error message

`atuin history tail` requires Atuin to be built with the `daemon` feature

What it means

`atuin history tail` is implemented on top of the daemon's streaming RPC and only exists when the binary is compiled with the `daemon` feature. Running a build without that feature bails with this message instead of attempting the command.

Solutions

  1. Install/build atuin with the daemon feature: `cargo install atuin --features daemon` (or ensure default features are on).
  2. Use a distro/official package that includes daemon support.
  3. Verify features with `atuin history tail --help` after reinstalling.

Example fix

// before
cargo install atuin --no-default-features --features client

// after
cargo install atuin --features daemon
Defensive patterns

Strategy: validation

Validate before calling

// shell check before invoking:
atuin history tail --help >/dev/null 2>&1 \
  || echo "this atuin build lacks the daemon feature; reinstall with --features daemon"

Try / catch

match run_history_tail().await {
    Err(e) if e.to_string().contains("daemon` feature") => {
        eprintln!("reinstall atuin with the daemon feature enabled");
    }
    other => other,
}

Prevention

When it happens

Trigger: Invoking `atuin history tail` on an atuin binary built without `--features daemon` (e.g. some distro packages or a default `cargo install atuin` depending on default features).

Common situations: Installing atuin from a source that strips optional features; building with `--no-default-features`; distro packages that exclude the daemon.

Related errors


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

Appendix: source

Thrown at crates/atuin/src/command/client/history.rs:1138

                )
                .await?
                {
                    println!("{id}");
                }

                Ok(())
            }
            Self::End {
                id, exit, duration, ..
            } => end_history_entry(settings, id, exit, duration).await,
            Self::Tail => {
                #[cfg(feature = "daemon")]
                {
                    return Self::handle_tail(settings).await;
                }

                #[cfg(not(feature = "daemon"))]
                bail!("`atuin history tail` requires Atuin to be built with the `daemon` feature");
            }
            cmd => {
                let context = current_context().await?;

                let db_path = &settings.db_path;
                let record_store_path = &settings.record_store_path;

                let db = Sqlite::new(db_path, settings.local_timeout).await?;
                let store = SqliteStore::new(record_store_path, settings.local_timeout).await?;

                let encryption_key = paseto_v4::Key::try_load_or_generate(&settings.key_path)
                    .context("could not load or generate encryption key")?;

                let host_id = Settings::host_id().await?;
                let history_store = HistoryStore::new(store.clone(), host_id, encryption_key);

                match cmd {
                    Self::List {

View on GitHub (pinned to 900007c480)