elkowar/eww · error
Failed to initialize tokio runtime for script var handlers
Error message
Failed to initialize tokio runtime for script var handlers
What it means
The script-var handler spawns a background thread that builds a multi-thread tokio runtime; if runtime construction fails, the `expect` panics inside that thread with this message. Without this runtime, poll and listen script vars cannot be processed.
Solutions
- Enable the required tokio features in Cargo.toml (`features = ["full"]` or at least `rt-multi-thread`, `macros`, `time`, `process`).
- Raise thread/process limits (ulimit -u) or relax container restrictions if worker-thread spawning fails.
- Check platform support for the multi-thread runtime.
Example fix
// Cargo.toml before
tokio = { version = "1", features = ["rt"] }
// after
tokio = { version = "1", features = ["rt-multi-thread", "macros", "time", "process"] } Defensive patterns
Strategy: try-catch
Validate before calling
// compile-time: tokio = { features = ["rt-multi-thread", "macros", "time", "process"] } Try / catch
let rt = tokio::runtime::Builder::new_multi_thread().enable_all().build();
if let Err(e) = rt { eprintln!("script-var handler disabled: {e}"); return; } Prevention
- Require rt-multi-thread and driver features for tokio.
- Watch thread limits (ulimit -u) in the deployment environment.
- Avoid building multi-thread runtimes on unsupported platforms.
When it happens
Trigger: Calling `ScriptVarHandler::init` when `Builder::new_multi_thread().enable_all().build()` returns an Err on the spawned thread.
Common situations: Tokio compiled without multi-thread scheduler or driver features; systems where thread/worker creation is restricted (ulimit, containers).
AI-assisted analysis of elkowar/eww@48f5aa8b37 (2026-09-08).
Data as JSON: /api/errors/d693e07315083597.
Report an issue: GitHub.
Appendix: source
Thrown at crates/eww/src/script_var_handler.rs:34
use tokio::{
io::{AsyncBufReadExt, BufReader},
sync::mpsc::UnboundedSender,
};
use tokio_util::sync::CancellationToken;
use yuck::config::script_var_definition::{ListenScriptVar, PollScriptVar, ScriptVarDefinition, VarSource};
/// Initialize the script var handler, and return a handle to that handler, which can be used to control
/// the script var execution.
pub fn init(evt_send: UnboundedSender<DaemonCommand>) -> ScriptVarHandlerHandle {
let (msg_send, mut msg_recv) = tokio::sync::mpsc::unbounded_channel();
let thread_handle = std::thread::Builder::new()
.name("outer-script-var-handler".to_string())
.spawn(move || {
let rt = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.thread_name("script-var-handler")
.build()
.expect("Failed to initialize tokio runtime for script var handlers");
rt.block_on(async {
let _: Result<_> = async {
let mut handler = ScriptVarHandler {
listen_handler: ListenVarHandler::new(evt_send.clone())?,
poll_handler: PollVarHandler::new(evt_send)?,
};
crate::loop_select_exiting! {
Some(msg) = msg_recv.recv() => match msg {
ScriptVarHandlerMsg::AddVar(var) => {
handler.add(var).await;
}
ScriptVarHandlerMsg::Stop(name) => {
handler.stop_for_variable(&name).await?;
}
ScriptVarHandlerMsg::StopAll => {
handler.stop_all().await;
break;
}View on GitHub (pinned to 48f5aa8b37)