RightNow-AI/openfang · critical

Failed to start OpenFang server

Error message

Failed to start OpenFang server

What it means

`run()` boots the embedded server via `server::start_server()` (crates/openfang-desktop/src/server.rs:66) and unwraps the result with `.expect("Failed to start OpenFang server")`. `start_server` returns `Box<dyn Error>` and can fail at `OpenFangKernel::boot`, binding the `TcpListener` on 127.0.0.1:0, reading the local address, or spawning the server thread. Any of these aborts desktop startup with this panic.

Source

Thrown at crates/openfang-desktop/src/lib.rs:44

    pub kernel: Arc<OpenFangKernel>,
    pub started_at: Instant,
}

/// Entry point for the Tauri application.
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    // Init tracing
    tracing_subscriber::fmt()
        .with_env_filter(
            tracing_subscriber::EnvFilter::try_from_default_env()
                .unwrap_or_else(|_| "openfang=info,tauri=info".into()),
        )
        .init();

    info!("Starting OpenFang Desktop...");

    // Boot kernel + embedded server (blocks until port is known)
    let server_handle = server::start_server().expect("Failed to start OpenFang server");
    let port = server_handle.port;
    let kernel_for_notifications = server_handle.kernel.clone();

    info!("OpenFang server running on port {port}");

    let url = format!("http://127.0.0.1:{port}");

    let mut builder = tauri::Builder::default()
        .plugin(tauri_plugin_notification::init())
        .plugin(tauri_plugin_shell::init())
        .plugin(tauri_plugin_dialog::init());

    // Desktop-only plugins
    #[cfg(desktop)]
    {
        builder = builder.plugin(tauri_plugin_single_instance::init(|app, _args, _cwd| {
            // Another instance tried to launch — focus the existing window
            if let Some(w) = app.get_webview_window("main") {

View on GitHub (pinned to acf2587e46)

Solutions

  1. Inspect the panic's underlying error source — `expect` prints the `Box<dyn Error>` message; fix that root cause (kernel config, secrets, port bind).
  2. Validate `~/.openfang/.env` and secrets.env are present and parseable before launching the desktop app.
  3. Check the environment allows binding sockets on 127.0.0.1 (firewall/seccomp/RLIMIT_NOFILE limits).
  4. Replace `.expect` with error propagation so `run()` can return a `Result` and show a dialog instead of crashing.

Example fix

// before
let server_handle = server::start_server().expect("Failed to start OpenFang server");

// after
let server_handle = server::start_server()
    .map_err(|e| anyhow!("Failed to start OpenFang server: {e}"))?;
Defensive patterns

Strategy: validation

Validate before calling

// preflight before run()
fn preflight() -> Result<(), String> {
    let env_path = dirs::home_dir().ok_or("no home dir")?.join(".openfang/.env");
    if !env_path.exists() { return Err(format!("missing {}", env_path.display())); }
    std::net::TcpListener::bind("127.0.0.1:0")
        .map_err(|e| format!("cannot bind loopback: {e}"))?;
    Ok(())
}

Try / catch

// propagate the boxed error instead of expect
let server_handle = server::start_server()
    .map_err(|e| anyhow!("Failed to start OpenFang server: {e}"))?;

Prevention

When it happens

Trigger: Kernel boot failure (bad config/secrets, provider/credential initialization errors), `TcpListener::bind("127.0.0.1:0")` failing (exhausted ephemeral ports, socket restrictions, no loopback), `local_addr()` failing, or `std::thread::Builder::spawn` failing (thread creation denied).

Common situations: Corrupt or missing `~/.openfang/.env` / secrets.env causing kernel boot errors, sandboxed or hardened environments that forbid socket creation, resource limits (RLIMIT_NPROC / fd exhaustion), or misconfigured containers without loopback networking.

Related errors


AI-assisted analysis of RightNow-AI/openfang@acf2587e46 (2026-09-02). Data as JSON: /api/errors/41568c2225bc1306. Report an issue: GitHub.