elkowar/eww · error
Failed to start script-var-handler thread
Error message
Failed to start script-var-handler thread
What it means
`ScriptVarHandler::init` spawns the OS thread that hosts the handler runtime. If `std::thread::Builder::spawn` fails, the `expect` panics with this message. Without the thread, script variables (poll/listen) will not be evaluated, so eww aborts rather than run with a broken var system.
Solutions
- Raise thread limits: `ulimit -u unlimited` (or a higher value) for the eww process.
- Check sandbox/container policies that block thread creation and allow them.
- Free system resources / investigate memory pressure that prevents spawning threads.
Example fix
// before (systemd unit) TasksMax=30 // after TasksMax=infinity
Defensive patterns
Strategy: retry
Validate before calling
let ok = std::thread::available_parallelism().is_ok(); // thread env sanity check (approximate)
Try / catch
match std::thread::Builder::new().name("outer-script-var-handler".into()).spawn(work) {
Ok(h) => h,
Err(e) => { eprintln!("handler thread spawn failed: {e}"); return ...; }
} Prevention
- Raise `ulimit -u` / systemd TasksMax for user services running eww.
- Avoid heavy thread consumers co-resident with eww in constrained containers.
- Monitor memory pressure that can make thread creation fail.
When it happens
Trigger: `ScriptVarHandler::init` when the OS refuses to spawn the "outer-script-var-handler" thread (resource exhaustion, thread limits, security restrictions).
Common situations: Hitting `ulimit -u` thread limits, running in restricted sandboxes/containers denying thread creation, low-memory conditions.
AI-assisted analysis of elkowar/eww@48f5aa8b37 (2026-09-08).
Data as JSON: /api/errors/2afd6c37a9f60029.
Report an issue: GitHub.
Appendix: source
Thrown at crates/eww/src/script_var_handler.rs:61
ScriptVarHandlerMsg::AddVar(var) => {
handler.add(var).await;
}
ScriptVarHandlerMsg::Stop(name) => {
handler.stop_for_variable(&name).await?;
}
ScriptVarHandlerMsg::StopAll => {
handler.stop_all().await;
break;
}
},
else => break,
};
Ok(())
}
.await;
})
})
.expect("Failed to start script-var-handler thread");
ScriptVarHandlerHandle { msg_send, thread_handle }
}
/// Handle to the script-var handling system.
pub struct ScriptVarHandlerHandle {
msg_send: UnboundedSender<ScriptVarHandlerMsg>,
thread_handle: std::thread::JoinHandle<()>,
}
impl ScriptVarHandlerHandle {
/// Add a new script-var that should be executed.
/// This is idempodent, meaning that running a definition that already has a script_var attached which is running
/// won't do anything.
pub fn add(&self, script_var: ScriptVarDefinition) {
crate::print_result_err!(
"while forwarding instruction to script-var handler",
self.msg_send.send(ScriptVarHandlerMsg::AddVar(script_var))
);View on GitHub (pinned to 48f5aa8b37)