denoland/deno · error

failed to locate output for HTML entry '{}'; {js_entry_name}

Error message

failed to locate output for HTML entry '{}'; {js_entry_name}

What it means

HTML bundling builds each page through a virtual entry module (name + '-deno-bundle-html.entry') and afterwards renames esbuild's outputs by looking them up under that internal virtual name (cli/tools/bundle/html.rs:493-513). This error means the expected JS output file for the virtual entry was not among esbuild's output files - an invariant break in the HTML pipeline (esbuild output-naming change, an entry whose scripts produced no JS chunk, or an output-name collision), not a mistake in your flags.

Source

Thrown at cli/tools/bundle/html.rs:509

    }

    let entry_name = format!("{}{}", self.entry_name, VIRTUAL_ENTRY_SUFFIX);
    let js_entry_name = format!("{}.js", entry_name);

    let mut js_out_no_hash = None;
    let js_out = html_output_files
      .get_and_update_path(&js_entry_name, |p, f| {
        let p = p.to_string_lossy();
        js_out_no_hash = Some(
          p.replace(entry_name.as_str(), &original_entry_name)
            .replace(&format!("-{}", f.hash), "")
            .into(),
        );

        p.replace(entry_name.as_str(), &original_entry_name).into()
      })
      .ok_or_else(|| {
        anyhow::anyhow!(
          "failed to locate output for HTML entry '{}'; {js_entry_name}",
          self.entry_name
        )
      })?;
    let html_out_path = js_out_no_hash
      .unwrap_or_else(|| js_out.clone())
      .with_extension("html");

    // esbuild emits the external/linked sourcemap (`*.js.map`) for the entry
    // under the internal virtual-entry name. Rename it to match the renamed JS
    // bundle (e.g. `index-HASH.js.map`) and fix the JS `sourceMappingURL`
    // reference so the emitted output doesn't leak the `deno-bundle-html.entry`
    // implementation detail. See denoland/deno#30750.
    let map_entry_name = format!("{}.js.map", entry_name);
    let mut old_map_name = None;
    let new_map_out =
      html_output_files.get_and_update_path(&map_entry_name, |p, _| {
        old_map_name = p

View on GitHub (pinned to 89f33cbef2)

Solutions

  1. Update Deno - the HTML bundling pipeline and its output-renaming are actively fixed; skew between esbuild naming and this lookup is a known fragility
  2. Bundle the script entry directly (deno bundle --outdir dist src/main.ts) to confirm the JS graph itself builds; if it does, the issue is HTML-specific - report it
  3. Simplify the HTML (temporarily remove sourcemap/naming/minify flags) to see whether the JS output reappears under the virtual name
  4. Report to denoland/deno with the HTML file and deno bundle invocation if it reproduces on the latest version

Example fix

# before: HTML entry fails to locate its JS output
deno bundle --outdir dist index.html
# after: unblock by bundling the page's script entry directly
deno bundle --outdir dist index.html.src/main.ts  # path of the <script src=...> target
# then file the HTML-path failure at github.com/denoland/deno/issues
Defensive patterns

Strategy: fallback

Validate before calling

# Smoke-test the page's script graph separately before the HTML bundle
deno bundle --outdir /tmp/smoke "$(grep -o 'src="[^"]*\.ts"' index.html | head -1 | cut -d'"' -f2)" \
  && deno bundle --outdir dist index.html || echo 'HTML bundling invariant broken - bundle script entry directly and report'

Try / catch

# Build script: fall back to bundling the script entry when HTML path fails
if ! deno bundle --outdir dist index.html; then
  echo 'falling back to script-entry bundle' >&2
  deno bundle --outdir dist js/main.ts
fi

Prevention

When it happens

Trigger: Bundling an .html entrypoint whose script graph yields no JS output file under the virtual entry name; esbuild version behavior change in entry-naming/hash placement; interaction of --minify/naming flags with the virtual-entry renaming; duplicate basenames colliding in HtmlOutputFiles' index.

Common situations: Early adopters of the HTML bundling feature after a Deno upgrade (esbuild pin moved); HTML pages referencing only CSS or empty scripts; pages whose script tags point at modules that esbuild tree-shakes to nothing.

Related errors


AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16). Data as JSON: /api/errors/4117db53ea0d026f. Report an issue: GitHub.