denoland/deno · error · anyhow::Error
module not found
Error message
module not found {} What it means
When Deno serializes a module graph into an eszip archive (deno compile / deno bundle internals), every visited specifier must be found in the graph via graph.try_get(). Ok(None) means the specifier was queued for visiting but no module exists for it in the graph that was passed in — the graph and the visit queue disagree, so the build fails with 'module not found <specifier>'.
Solutions
- Re-run `deno cache <entry>` (or delete DENO_DIR and retry) so every specifier is freshly loaded before compiling
- Run `deno check <entry>` first — unresolved imports surface there with better diagnostics
- Ensure the graph passed to eszip was built from the same entry point and loader that produced the visit queue (don't mix graphs across runs)
- If a third-party dependency fails to resolve, pin a working version in the import map or package.json
Example fix
# before deno compile src/mod.ts # module not found https://example.com/lib.js # after deno cache src/mod.ts && deno compile src/mod.ts
Defensive patterns
Strategy: try-catch
Validate before calling
# Make every specifier resolvable BEFORE compiling # (a successful cache guarantees graph.try_get() finds each module) deno check --all src/mod.ts && deno cache src/mod.ts
Try / catch
// Tooling around `deno compile`
const p = new Deno.Command("deno", { args: ["compile", "-o", "app", "src/mod.ts"] });
const { success, stderr } = await p.output();
const err = new TextDecoder().decode(stderr);
if (!success && err.includes("module not found")) {
const spec = err.match(/module not found (\S+)/)?.[1];
// re-cache just that specifier: deno cache <spec>, then retry
} Prevention
- Run deno cache/check in CI before compile steps
- Don't build graphs and eszips from different sessions or entry points
- Keep remote imports version-pinned so caches stay reproducible
When it happens
Trigger: Building an eszip from a graph that was constructed with a different entry point or with errors skipped; a dependency edge (e.g. from a resolved import in a cached package.json or import map) pointing at a specifier never loaded into the graph; file deleted or remote module evicted from cache between graph construction and serialization.
Common situations: deno compile failing after a DENO_DIR cache purge or when --no-remote-style restrictions excluded a module; mismatched graphs after editing entry points while reusing a stale in-process graph; tooling built on the eszip crate passing a graph and visitor set built from separate runs.
Related errors
- unsupported media type
- failed to load
- Could not resolve package req
- An executable name was not provided. One could not be…
- Deno.bundle() is not available in compiled binaries (`deno…
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/78e6ebb4a929eb3d.
Report an issue: GitHub.
Appendix: source
Thrown at libs/eszip/v2.rs:1367
fn visit_module<'a>(
graph: &'a ModuleGraph,
module_kind_provider: &dyn ModuleKindResolver,
parser: CapturingEsParser,
transpile_options: &TranspileOptions,
emit_options: &EmitOptions,
modules: &mut LinkedHashMap<String, EszipV2Module>,
visited: ToVisit,
relative_file_base: Option<EszipRelativeFileBaseUrl>,
npm_packages: Option<&mut FromGraphNpmPackages>,
npm_snapshot: &ValidSerializedNpmResolutionSnapshot,
) -> Result<
Option<Box<dyn DoubleEndedIterator<Item = ToVisit<'a>> + 'a>>,
anyhow::Error,
> {
let module = match graph.try_get(visited.specifier()) {
Ok(Some(module)) => module,
Ok(None) => {
return Err(anyhow::anyhow!(
"module not found {}",
visited.specifier()
));
}
Err(err) => {
if visited.is_dynamic() {
// dynamic imports are allowed to fail
return Ok(None);
}
return Err(anyhow::anyhow!(
"failed to load '{}': {}",
visited.specifier(),
err
));
}
};
let specifier_key =View on GitHub (pinned to 9ad36f7a2c)