elkowar/eww · error
No root scope in graph
Error message
No root scope in graph
What it means
scope_graph.global_scope() indexes the graph at root_index and expects the scope to exist. If the root scope is missing, the scope graph was built or mutated incorrectly — again an internal invariant failure rather than something a config value directly controls.
Solutions
- Fix the config error that prevented the root scope from being created: run `eww logs` and validate the yuck file (`xmllint` on widget XML).
- Restart the daemon (`eww kill && eww daemon`) to rebuild the scope graph from scratch.
- Update eww — if the graph constructor can produce a missing root, it is a bug worth reporting upstream.
- Guard the accessor: return a Result or fall back to an empty scope instead of expecting.
Example fix
// before
pub fn global_scope(&self) -> &Scope {
self.graph.scope_at(self.root_index).expect("No root scope in graph")
}
// after
pub fn global_scope(&self) -> Result<&Scope> {
self.graph.scope_at(self.root_index).context("No root scope in graph")
} Defensive patterns
Strategy: validation
Validate before calling
// verify the graph root exists before use
if graph.scope_at(graph.root_index).is_none() { return Err(anyhow!("scope graph has no root; config failed to parse")); } Try / catch
match scope_graph.global_scope_checked() {
Ok(root) => /* use root */,
Err(e) => log::error!("scope graph unusable: {} — fix config and restart daemon", e),
} Prevention
- Validate yuck config before hot reload (eww logs / xmllint)
- Ensure the root scope is always inserted at graph construction
- Restart daemon after any scope-graph error instead of continuing on a broken graph
- Add a unit test that every constructed ScopeGraph resolves root_index
When it happens
Trigger: Calling global_scope() (directly or via currently_unused_globals) on a ScopeGraph whose root_index does not resolve, e.g. a graph constructed from an empty/failed parse where the root scope was never inserted or was removed.
Common situations: Seen during config parsing/reload when the widget hierarchy failed to build (malformed yuck XML) so the root scope never got created, or during teardown/rebuild races on hot reload.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- OneToNElementsMap got into inconsistent state
- Error opening log file
- Something went wrong unindenting the string
- Could not get default gtk theme
- no pixbuf from theme.load_icon despite no error
AI-assisted analysis of elkowar/eww@48f5aa8b37 (2026-09-08).
Data as JSON: /api/errors/7b93aef5a3d04faa.
Report an issue: GitHub.
Appendix: source
Thrown at crates/eww/src/state/scope_graph.rs:136
pub fn visualize(&self) -> String {
self.graph.visualize()
}
pub fn currently_used_globals(&self) -> HashSet<VarName> {
self.variables_used_in_self_or_subscopes_of(self.root_index)
}
pub fn currently_unused_globals(&self) -> HashSet<VarName> {
let used_variables = self.currently_used_globals();
self.global_scope().data.keys().cloned().collect::<HashSet<_>>().difference(&used_variables).cloned().collect()
}
pub fn scope_at(&self, index: ScopeIndex) -> Option<&Scope> {
self.graph.scope_at(index)
}
pub fn global_scope(&self) -> &Scope {
self.graph.scope_at(self.root_index).expect("No root scope in graph")
}
/// Evaluate a [SimplExpr] in a given scope. This will return `Err` if any referenced variables
/// are not available in the scope. If evaluation fails for other reasons (bad types, etc)
/// this will print a warning and return an empty string instead.
pub fn evaluate_simplexpr_in_scope(&self, index: ScopeIndex, expr: &SimplExpr) -> Result<DynVal> {
let needed_vars = self.lookup_variables_in_scope(index, &expr.collect_var_refs())?;
// TODORW
// TODO allowing it to fail here is painfully ugly
match expr.eval(&needed_vars) {
Ok(value) => Ok(value),
Err(err) => {
error_handling_ctx::print_error(anyhow!(err));
Ok(DynVal::from(""))
}
}
}
View on GitHub (pinned to 48f5aa8b37)