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
- Inspect the panic's underlying error source — `expect` prints the `Box<dyn Error>` message; fix that root cause (kernel config, secrets, port bind).
- Validate `~/.openfang/.env` and secrets.env are present and parseable before launching the desktop app.
- Check the environment allows binding sockets on 127.0.0.1 (firewall/seccomp/RLIMIT_NOFILE limits).
- 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
- Keep ~/.openfang/.env and secrets.env valid; validate on first run
- Verify loopback socket binding is permitted in sandboxed/containerized deployments
- Watch file-descriptor and thread limits under load
- Return Result from run() rather than expect-ing server startup
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.