astrid-runtime/astrid · error · anyhow::Error

Failed to connect to daemon. Check logs: {}

Error message

Failed to connect to daemon. Check logs: {}

What it means

This error wraps any failure to establish a connection to the Astrid daemon during CLI bootstrap. The original error (e.g. connection refused, daemon not running, socket stale) is preserved via anyhow context, and a log directory hint is appended so the developer can inspect daemon logs. The library throws it because the CLI cannot proceed to the chat/REPL session without a live daemon connection.

Source

Thrown at crates/astrid-cli/src/bootstrap.rs:255

            drop(daemon_child);
            c
        },
        Err(e) => {
            if let Some(child) = daemon_child {
                // A live first cutover must not be SIGKILL'd because connect
                // raced the ready sentinel.
                commands::daemon::disown_if_still_running(child);
            }
            let log_hint = astrid_core::dirs::AstridHome::resolve().map_or_else(
                |_| "Failed to connect to daemon".to_string(),
                |h| {
                    format!(
                        "Failed to connect to daemon. Check logs: {}",
                        h.log_dir().display()
                    )
                },
            );
            return Err(anyhow::Error::new(e).context(log_hint));
        },
    };

    crate::commands::chat::run_chat(&mut client, &session_id, INITIAL_TUI_MODEL_LABEL, format).await
}

#[cfg(test)]
mod tests {
    use super::{INITIAL_TUI_MODEL_LABEL, selected_workspace_root};

    #[test]
    fn interactive_tui_starts_without_a_host_model_label() {
        assert_eq!(INITIAL_TUI_MODEL_LABEL, "");
    }

    #[test]
    fn explicit_workspace_root_wins_over_current_directory() {
        let explicit = tempfile::tempdir().expect("explicit workspace");

View on GitHub (pinned to affd8760f4)

Solutions

  1. Check the daemon logs at the directory printed in the error (h.log_dir()) for the root cause
  2. Start the daemon manually, then retry the CLI
  3. Remove any stale socket/pid files left by a crashed daemon and restart
  4. Verify the daemon address/port configuration matches what the daemon is bound to
  5. Check file permissions on the daemon socket directory

Example fix

// before: CLI fails with 'Failed to connect to daemon'
astrid chat
// after: ensure daemon is up first
astrid daemon start && astrid chat
Defensive patterns

Strategy: try-catch

Validate before calling

// Before launching the chat session, check if the daemon socket is reachable
fn daemon_reachable(socket_path: &std::path::Path) -> bool {
    socket_path.exists() // and/or attempt a lightweight connect/ping
}

Try / catch

match run_or_connect().await {
    Ok(session) => session,
    Err(e) if e.to_string().contains("Failed to connect to daemon") => {
        eprintln!("{}\nCheck daemon logs, then start the daemon and retry.", e);
        std::process::exit(1);
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling run_or_connect when the daemon is not running, crashed, or listening on a stale/incorrect socket or port; daemon logs are surfaced via h.log_dir().

Common situations: Starting the CLI before launching the daemon; daemon died after a previous run leaving a stale socket; wrong daemon address in config; insufficient permissions to open the socket; daemon startup failures visible only in its log files.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/03d40c8e8582cf4d. Report an issue: GitHub.