{"record":{"id":"1b908a551433f493","repo":"denoland/deno","slug":"displaying-graphs-that-have-multiple-roots-is-not","errorCode":null,"errorMessage":"displaying graphs that have multiple roots is not supported.","messagePattern":"displaying graphs that have multiple roots is not supported\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/tools/info.rs","lineNumber":543,"sourceCode":"      Some((npm_resolver, npm_snapshot)) => {\n        NpmInfo::build(graph, npm_resolver, npm_snapshot)\n      }\n      None => NpmInfo::default(),\n    };\n    Self {\n      graph,\n      npm_info,\n      seen: Default::default(),\n    }\n    .into_writer(writer)\n  }\n\n  fn into_writer<TWrite: Write>(\n    mut self,\n    writer: &mut TWrite,\n  ) -> Result<(), AnyError> {\n    if self.graph.roots.is_empty() || self.graph.roots.len() > 1 {\n      bail!(\"displaying graphs that have multiple roots is not supported.\");\n    }\n\n    let root_specifier = self.graph.resolve(&self.graph.roots[0]);\n    match self.graph.try_get(root_specifier) {\n      Ok(Some(root)) => {\n        let maybe_cache_info = match root {\n          Module::Js(module) => module.maybe_cache_info.as_ref(),\n          Module::Json(module) => module.maybe_cache_info.as_ref(),\n          Module::Wasm(module) => module.maybe_cache_info.as_ref(),\n          Module::Node(_) | Module::Npm(_) | Module::External(_) => None,\n        };\n        if let Some(cache_info) = maybe_cache_info\n          && let Some(local) = &cache_info.local\n        {\n          writeln!(\n            writer,\n            \"{} {}\",\n            colors::bold(\"local:\"),","sourceCodeStart":525,"sourceCodeEnd":561,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/cli/tools/info.rs#L525-L561","documentation":"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.","triggerScenarios":"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).","commonSituations":"Embedders reusing deno's info renderer with graphs built from multiple entry modules; edge-case workspace configurations on older Deno builds.","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"],"exampleFix":"# before (embedding, one graph for many entries)\n# graph built with roots [main.ts, worker.ts] -> bail\n\n# after\n# build one graph per root, render each:\n# for root in roots: GraphDisplayContext::write(&graph_for(root), ...)","handlingStrategy":"type-guard","validationCode":"# CLI side: always give info exactly one specifier\ndeno info src/main.ts","typeGuard":"// embedding (Rust): guard before rendering\nfn can_display(graph: &deno_graph::ModuleGraph) -> bool {\n  graph.roots.len() == 1\n}\n// if !can_display(&graph) { split per root or bail with your own message }","tryCatchPattern":"When embedding, catch the bail and fall back to rendering each root's subgraph individually (one GraphDisplayContext per root).","preventionTips":["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"],"tags":["info","module-graph","internal","invariant"],"backgroundTag":"multi-root-module-graph","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}