denoland/deno · error · anyhow::Error

failed to load

Error message

failed to load '{}': {}

What it means

During eszip construction, graph.try_get(specifier) can also return Err — the module exists in the graph but loading it produced an error (fetch failure, permission denial, syntax error, unstable loader state). For dynamic imports this is tolerated (the visitor returns Ok(None) and the import is simply not embedded), but for a statically reachable specifier the error is propagated as "failed to load '<specifier>': <err>".

Solutions

  1. Read the suffix after the colon — it carries the root cause (HTTP status, ENOENT, parse error)
  2. Run `deno cache <entry>` to reproduce the fetch/load failure with full diagnostics, fix it (auth token, network, file path), then retry compile
  3. For private registries, re-export DENO_AUTH_TOKENS / .npmrc credentials in the build environment
  4. Grant the permissions the build needs (network for remote deps, read for local files) or vendor the dependencies

Example fix

# before
deno compile src/mod.ts  # failed to load 'https://example.com/lib.js': Not Found

# after
# fix or pin the broken dependency, then
import { lib } from "https://example.com/lib.js@0.4.2";
deno cache src/mod.ts && deno compile src/mod.ts
Defensive patterns

Strategy: try-catch

Validate before calling

# Preflight: surface loader errors with full diagnostics first
deno check --all src/mod.ts  # fetch + parse everything compile will load

Try / catch

const { success, stderr } = await new Deno.Command("deno", { args: ["compile", "src/mod.ts"] }).output();
const err = new TextDecoder().decode(stderr);
const m = err.match(/failed to load '(\S+)': (.+)/);
if (!success && m) {
  const [, specifier, cause] = m;
  if (/40[134]|Not Found/i.test(cause)) pinOrRemoveDependency(specifier);
  else if (/enoent|permission/i.test(cause)) fixLocalPathOrPerms(specifier);
}

Prevention

When it happens

Trigger: A static import of a URL that returned 404/500 while building the graph; a local file with unreadable permissions; a TypeScript/JSX file that failed parsing; a data:/npm: specifier the loader rejected. The underlying loader error text is appended after the colon.

Common situations: deno compile against a remote server that is down or rate-limiting; private registry auth token expired so npm/jsr fetches fail; file locked by antivirus on Windows; running compile with restricted --allow-net/--allow-read so the loader could not fetch/read dependencies.

Related errors


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

Appendix: source

Thrown at libs/eszip/v2.rs:1377

      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 =
        resolve_specifier_key(module.specifier(), relative_file_base)?;
      if modules.contains_key(specifier_key.as_ref()) {
        return Ok(None);
      }

      match module {
        deno_graph::Module::Js(module) => {
          let source: Arc<[u8]>;
          let source_map: Arc<[u8]>;
          match module.media_type {

View on GitHub (pinned to 9ad36f7a2c)