{"record":{"id":"46712d4b6d316e38","repo":"RightNow-AI/openfang","slug":"failed-to-create-tokio-runtime-for-embedded-server","errorCode":null,"errorMessage":"Failed to create tokio runtime for embedded server","messagePattern":"Failed to create tokio runtime for embedded server","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/openfang-desktop/src/server.rs","lineNumber":94,"sourceCode":"\n    // Bind to a random free port on localhost (main thread — guarantees port)\n    let std_listener = TcpListener::bind(\"127.0.0.1:0\")?;\n    let port = std_listener.local_addr()?.port();\n    let listen_addr: SocketAddr = std_listener.local_addr()?;\n\n    info!(\"OpenFang embedded server bound to http://127.0.0.1:{port}\");\n\n    let (shutdown_tx, shutdown_rx) = watch::channel(false);\n    let kernel_clone = kernel.clone();\n    let shutdown_initiated = Arc::new(AtomicBool::new(false));\n\n    let server_thread = std::thread::Builder::new()\n        .name(\"openfang-server\".into())\n        .spawn(move || {\n            let rt = tokio::runtime::Builder::new_multi_thread()\n                .enable_all()\n                .build()\n                .expect(\"Failed to create tokio runtime for embedded server\");\n\n            rt.block_on(async move {\n                // start_background_agents() uses tokio::spawn, so it must\n                // run inside a tokio runtime context.\n                kernel_clone.start_background_agents();\n                run_embedded_server(kernel_clone, std_listener, listen_addr, shutdown_rx).await;\n            });\n        })?;\n\n    Ok(ServerHandle {\n        port,\n        kernel,\n        shutdown_tx,\n        server_thread: Some(server_thread),\n        shutdown_initiated,\n    })\n}\n","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/RightNow-AI/openfang/blob/acf2587e46be174c10200489c9a2d23a39a98aeb/crates/openfang-desktop/src/server.rs#L76-L112","documentation":"This panic comes from an `.expect()` in start_server (crates/openfang-desktop/src/server.rs:94) when `tokio::runtime::Builder::new_multi_thread().enable_all().build()` returns an Err. The code spawns a dedicated OS thread and builds a fresh multi-threaded tokio runtime on it to run the embedded axum server, since tokio::spawn-based background agents require a runtime context. Runtime construction can fail because the builder cannot spawn worker threads or initialize internal resources (I/O or time drivers, parking/condvar primitives).","triggerScenarios":"Calling tokio Runtime::build() inside the spawned 'openfang-server' thread when the OS refuses to create worker threads (thread count/RLIMIT limits, out of memory), or when the tokio io/time driver resources cannot be created (e.g. epoll/kqueue fd exhaustion).","commonSituations":"Host environments with very low thread or file-descriptor limits (containers, CI sandboxes), heavily memory-constrained machines, or misconfigured tokio features (missing 'rt-multi-thread'/'macros' features is caught at compile time, but runtime resource exhaustion hits here).","solutions":["Check OS resource limits (ulimit -u threads, ulimit -n file descriptors) and raise them for the process.","Reduce worker thread pressure: configure .worker_threads(N) with a small N to lower thread creation cost.","Ensure the process is not near its memory/thread budget before start_server is called (leaked threads from earlier failures).","Replace the expect with proper error propagation (return Result from start_server) and surface the underlying io::Error to logs for diagnosis.","Verify tokio crate version/features are consistent across the workspace to avoid driver initialization issues."],"exampleFix":"// before\nlet rt = tokio::runtime::Builder::new_multi_thread()\n    .enable_all()\n    .build()\n    .expect(\"Failed to create tokio runtime for embedded server\");\n// after\nlet rt = tokio::runtime::Builder::new_multi_thread()\n    .enable_all()\n    .worker_threads(2)\n    .build()\n    .map_err(|e| ServerError::RuntimeInit(e.to_string()))?;","handlingStrategy":"try-catch","validationCode":"// Before spawning the server thread, probe resource headroom\nlet max_threads = unsafe { libc::sysconf(libc::_SC_THREAD_THREADS_MAX) };\nif max_threads != -1 && max_threads < 8 {\n    return Err(\"too few threads allowed for tokio runtime\");\n}","typeGuard":null,"tryCatchPattern":"let rt = tokio::runtime::Builder::new_multi_thread()\n    .enable_all()\n    .build();\nmatch rt {\n    Ok(rt) => { /* block_on(...) */ }\n    Err(e) => log::error!(\"tokio runtime init failed: {e}\"), // propagate to UI/notification\n}","preventionTips":["Run the app with sane ulimits (threads and file descriptors) in containers and CI.","Avoid spawning unbounded threads before start_server; use a thread pool.","Configure an explicit small worker_threads count so runtime init needs minimal resources.","Never expect() on runtime build in shipped code — return Result and degrade gracefully (e.g. fall back to no embedded server)."],"tags":["rust","tokio","runtime","desktop","threading"],"backgroundTag":"tokio-runtime-build-failed","analyzedSha":"acf2587e46be174c10200489c9a2d23a39a98aeb","analyzedAt":"2026-09-02T22:42:28.464Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}