denoland/deno · error
displaying graphs that have multiple roots is not supported.
Error message
displaying graphs that have multiple roots is not supported.
What it means
The `deno info` renderer (GraphDisplayContext::into_writer) requires a module graph with exactly one root so it can walk dependencies from a single entrypoint. This guard fires when the graph has zero roots or more than one root. From the CLI, `deno info` passes a single file/URL argument, so hitting this usually means unusual workspace state or an internal/embedding caller that built a multi-root graph.
Source
Thrown at cli/tools/info.rs:543
Some((npm_resolver, npm_snapshot)) => {
NpmInfo::build(graph, npm_resolver, npm_snapshot)
}
None => NpmInfo::default(),
};
Self {
graph,
npm_info,
seen: Default::default(),
}
.into_writer(writer)
}
fn into_writer<TWrite: Write>(
mut self,
writer: &mut TWrite,
) -> Result<(), AnyError> {
if self.graph.roots.is_empty() || self.graph.roots.len() > 1 {
bail!("displaying graphs that have multiple roots is not supported.");
}
let root_specifier = self.graph.resolve(&self.graph.roots[0]);
match self.graph.try_get(root_specifier) {
Ok(Some(root)) => {
let maybe_cache_info = match root {
Module::Js(module) => module.maybe_cache_info.as_ref(),
Module::Json(module) => module.maybe_cache_info.as_ref(),
Module::Wasm(module) => module.maybe_cache_info.as_ref(),
Module::Node(_) | Module::Npm(_) | Module::External(_) => None,
};
if let Some(cache_info) = maybe_cache_info
&& let Some(local) = &cache_info.local
{
writeln!(
writer,
"{} {}",
colors::bold("local:"),View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Run `deno info <single-file-or-url>` so the graph has exactly one root
- If embedding, split the graph per root and render each root separately
- Update Deno — if plain `deno info <file>` triggers this, it is a bug worth reporting with the repro
Example fix
# before (embedding, one graph for many entries) # graph built with roots [main.ts, worker.ts] -> bail # after # build one graph per root, render each: # for root in roots: GraphDisplayContext::write(&graph_for(root), ...)
Defensive patterns
Strategy: type-guard
Validate before calling
# CLI side: always give info exactly one specifier deno info src/main.ts
Type guard
// embedding (Rust): guard before rendering
fn can_display(graph: &deno_graph::ModuleGraph) -> bool {
graph.roots.len() == 1
}
// if !can_display(&graph) { split per root or bail with your own message } Try / catch
When embedding, catch the bail and fall back to rendering each root's subgraph individually (one GraphDisplayContext per root).
Prevention
- Pass a single file/URL per `deno info` invocation
- When building graphs programmatically, keep one graph per entrypoint
- Treat this message on plain CLI usage as a bug and update/report
When it happens
Trigger: Calling GraphDisplayContext::write with a graph whose roots Vec is empty or contains 2+ specifiers (e.g. building one graph for several entrypoints and rendering it); CLI `deno info` hitting a code path that produced an empty/multi-root graph (a Deno bug in that scenario).
Common situations: Embedders reusing deno's info renderer with graphs built from multiple entry modules; edge-case workspace configurations on older Deno builds.
Related errors
- an internal error occurred
- Empty selector
- Empty node
- Multiple selectors not allowed here
- ${name} is already registered
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/1b908a551433f493.
Report an issue: GitHub.