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

  1. Run `deno info <single-file-or-url>` so the graph has exactly one root
  2. If embedding, split the graph per root and render each root separately
  3. 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

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


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/1b908a551433f493. Report an issue: GitHub.