{"record":{"id":"6024c026a336f984","repo":"elkowar/eww","slug":"failed-to-initialize-tokio-runtime-6024c0","errorCode":null,"errorMessage":"Failed to initialize tokio runtime","messagePattern":"Failed to initialize tokio runtime","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/eww/src/widgets/systray.rs","lineNumber":33,"sourceCode":"\nasync fn dbus_session() -> zbus::Result<&'static DBusSession> {\n    // TODO make DBusSession reference counted so it's dropped when not in use?\n\n    static DBUS_STATE: tokio::sync::OnceCell<DBusSession> = tokio::sync::OnceCell::const_new();\n    DBUS_STATE\n        .get_or_try_init(|| async {\n            let con = zbus::Connection::session().await?;\n            notifier_host::Watcher::new().attach_to(&con).await?;\n\n            let (_, snw) = notifier_host::register_as_host(&con).await?;\n\n            Ok(DBusSession { snw })\n        })\n        .await\n}\n\nfn run_async_task<F: Future>(f: F) -> F::Output {\n    let rt = tokio::runtime::Builder::new_current_thread().enable_all().build().expect(\"Failed to initialize tokio runtime\");\n    rt.block_on(f)\n}\n\npub struct Props {\n    icon_size_tx: tokio::sync::watch::Sender<i32>,\n    pub prepend_new: Rc<RefCell<bool>>,\n}\n\nimpl Props {\n    pub fn new() -> Self {\n        let (icon_size_tx, _) = tokio::sync::watch::channel(24);\n        Self { icon_size_tx, prepend_new: Rc::new(RefCell::new(false)) }\n    }\n\n    pub fn icon_size(&self, value: i32) {\n        let _ = self.icon_size_tx.send_if_modified(|x| {\n            if *x == value {\n                false","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/elkowar/eww/blob/48f5aa8b379adf29da0b0bb9ca04164f65d8bdaa/crates/eww/src/widgets/systray.rs#L15-L51","documentation":"run_async_task builds a current_thread tokio runtime on the fly and blocks on the given future; the expect panics if runtime creation fails. This means the OS refused to create the runtime's backing resources (blocking pool threads, timers), typically a thread/PID or memory limit.","triggerScenarios":"run_async_task invoked (e.g. for item_is_menu DBus calls in the systray) when RLIMIT_NPROC is exhausted, the pids cgroup limit is hit, or memory allocation for the runtime fails. Creating a fresh runtime per call also amplifies the chance of transient resource pressure.","commonSituations":"Systems under heavy thread churn, systray code invoked many times in quick succession on a resource-starved machine, sandboxed environments with strict limits.","solutions":["Raise thread/PID limits (ulimit -u, TasksMax, container pids limit).","Reuse a single shared runtime Handle instead of building a runtime per call — fewer resources and no repeated init failures.","Retry the task once after a brief sleep if the failure was transient resource pressure.","Return a Result from run_async_task so the caller (systray icon code) can degrade gracefully instead of panicking."],"exampleFix":"// before\nfn run_async_task<F: Future>(f: F) -> F::Output {\n    let rt = tokio::runtime::Builder::new_current_thread().enable_all().build().expect(\"Failed to initialize tokio runtime\");\n    rt.block_on(f)\n}\n// after\nfn run_async_task<F: Future>(f: F) -> Option<F::Output> {\n    let rt = tokio::runtime::Builder::new_current_thread().enable_all().build().ok()?;\n    Some(rt.block_on(f))\n}","handlingStrategy":"fallback","validationCode":"// reuse a lazily-initialized global runtime instead of building per call\nstatic RT: OnceLock<tokio::runtime::Runtime> = OnceLock::new();","typeGuard":null,"tryCatchPattern":"match tokio::runtime::Builder::new_current_thread().enable_all().build() {\n    Ok(rt) => rt.block_on(f),\n    Err(e) => { log::error!(\"runtime init failed: {}\", e); unreachable_fallback() }\n}","preventionTips":["Build one shared runtime (OnceLock/lazy_static) rather than per-call runtimes","Keep system thread limits generous","Avoid invoking the systray path in extremely constrained sandboxes","Return Option/Result so callers can degrade gracefully"],"tags":["tokio","runtime","systray","resource-limits"],"backgroundTag":"module-init-failed","analyzedSha":"48f5aa8b379adf29da0b0bb9ca04164f65d8bdaa","analyzedAt":"2026-09-08T03:13:26.897Z","contentChangedAt":"2026-09-08T03:13:26.897Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}