denoland/deno · error
--outdir is required when bundling HTML entrypoints
Error message
--outdir is required when bundling HTML entrypoints
What it means
`deno bundle` refuses to bundle HTML entrypoints without `--outdir`. An HTML bundle produces several files (hash-renamed JS, sourcemaps, patched HTML), so stdout output or a single-file target is impossible; the command fails up-front with this message.
Solutions
- Pass an output directory: `deno bundle --outdir=dist index.html`
- If you wanted a single-file JS bundle, point the command at the script module (e.g. `src/main.ts`) instead of the HTML file
Example fix
# before deno bundle index.html # after deno bundle --outdir=dist index.html
Defensive patterns
Strategy: validation
Validate before calling
// Wrapper: require --outdir when any entry ends with .html
const entries = Deno.args.filter((a) => !a.startsWith("-"));
if (
entries.some((e) => e.endsWith(".html")) &&
!Deno.args.some((a) => a.startsWith("--outdir"))
) {
throw new Error("HTML entrypoints require --outdir");
} Prevention
- Always pair HTML entries with --outdir
- Define bundle commands as deno.json tasks so flags are encoded once
- Treat stdout-bundle habits as JS-only
When it happens
Trigger: Running `deno bundle page.html` (any invocation whose entrypoints include an HTML file) without an `--outdir` flag.
Common situations: Habit from JS bundling where `deno bundle mod.ts` prints to stdout; CI scripts and npm-style tasks that call `deno bundle` without an output directory.
Understand the failure class
Background: "--flag is required" and "must specify" CLI errors: how missing-required-flag validation works and how to fix it — this error's family across 20 libraries.
Related errors
- --output is not supported with HTML entrypoints; use…
- failed to locate output for HTML entry
- Deno.bundle() is not available in compiled binaries (`deno…
- Entry point must be a file
- ERR_WORKER_INVALID_EXEC_ARGV
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/2cc65e0932c9d5f0.
Report an issue: GitHub.
Appendix: source
Thrown at cli/tools/bundle/mod.rs:148
init_cwd,
npm_resolver,
node_resolver,
);
plugin_handler.prepare_module_load(&roots).await?;
let graph = plugin_handler.module_graph_container.graph();
let mut fully_resolved_roots = IndexSet::with_capacity(graph.roots.len());
for root in &graph.roots {
fully_resolved_roots.insert(graph.resolve(root).clone());
}
*plugin_handler.resolved_roots.write() = Arc::new(fully_resolved_roots);
Ok(BundlerInput::Entrypoints(
roots.into_iter().map(|e| ("".into(), e.into())).collect(),
))
} else {
// require an outdir when any HTML is present
if bundle_flags.output_dir.is_none() {
return Err(deno_core::anyhow::anyhow!(
"--outdir is required when bundling HTML entrypoints",
));
}
if bundle_flags.output_path.is_some() {
return Err(deno_core::anyhow::anyhow!(
"--output is not supported with HTML entrypoints; use --outdir",
));
}
// Prepare HTML pages and temp entry modules
let mut html_pages = Vec::new();
let mut to_cache_urls = Vec::new();
let mut entries: Vec<(String, String)> = Vec::new();
let virtual_modules = Arc::new(VirtualModules::new());
for html_path in &html_paths {
let entry = html::load_html_entrypoint(
init_cwd,View on GitHub (pinned to 9ad36f7a2c)