{"record":{"id":"2cc65e0932c9d5f0","repo":"denoland/deno","slug":"outdir-is-required-when-bundling-html-entrypoint","errorCode":null,"errorMessage":"--outdir is required when bundling HTML entrypoints","messagePattern":"--outdir is required when bundling HTML entrypoints","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/tools/bundle/mod.rs","lineNumber":148,"sourceCode":"      init_cwd,\n      npm_resolver,\n      node_resolver,\n    );\n    plugin_handler.prepare_module_load(&roots).await?;\n    let graph = plugin_handler.module_graph_container.graph();\n    let mut fully_resolved_roots = IndexSet::with_capacity(graph.roots.len());\n    for root in &graph.roots {\n      fully_resolved_roots.insert(graph.resolve(root).clone());\n    }\n    *plugin_handler.resolved_roots.write() = Arc::new(fully_resolved_roots);\n\n    Ok(BundlerInput::Entrypoints(\n      roots.into_iter().map(|e| (\"\".into(), e.into())).collect(),\n    ))\n  } else {\n    // require an outdir when any HTML is present\n    if bundle_flags.output_dir.is_none() {\n      return Err(deno_core::anyhow::anyhow!(\n        \"--outdir is required when bundling HTML entrypoints\",\n      ));\n    }\n    if bundle_flags.output_path.is_some() {\n      return Err(deno_core::anyhow::anyhow!(\n        \"--output is not supported with HTML entrypoints; use --outdir\",\n      ));\n    }\n\n    // Prepare HTML pages and temp entry modules\n    let mut html_pages = Vec::new();\n    let mut to_cache_urls = Vec::new();\n    let mut entries: Vec<(String, String)> = Vec::new();\n    let virtual_modules = Arc::new(VirtualModules::new());\n\n    for html_path in &html_paths {\n      let entry = html::load_html_entrypoint(\n        init_cwd,","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/denoland/deno/blob/89f33cbef296a2b287f323d42de54c871fa69c77/cli/tools/bundle/mod.rs#L130-L166","documentation":"Bundling an HTML entrypoint emits multiple files per page (rewritten .html, .js, .css, sourcemaps) that must live in a directory; a single destination or stdout cannot represent them. When any resolved entrypoint is HTML (is_html_entrypoint) and bundle_flags.output_dir is None, the CLI rejects the invocation up front (cli/tools/bundle/mod.rs:146-151).","triggerScenarios":"'deno bundle index.html' or 'deno bundle page.html style.css' without --outdir; scripts paired with an HTML file so the HTML branch is taken; CI scripts migrating from 'deno bundle src/main.ts out.js' to an HTML page and keeping the old shape.","commonSituations":"First attempt at the HTML bundling feature; mixing HTML and script entrypoints in one command; build pipelines that assume bundle always writes one file.","solutions":["Add --outdir: 'deno bundle --outdir dist index.html'","If you wanted a single JS file, bundle the script the HTML references instead of the HTML page","Update build scripts/ci.yml that construct the deno bundle command to pass --outdir for HTML targets"],"exampleFix":"# before\ndeno bundle index.html\n# after\ndeno bundle --outdir dist index.html","handlingStrategy":"validation","validationCode":"#!/usr/bin/env bash\n# Refuse to construct an invalid command: HTML entries require --outdir\nentry=\"$1\"; shift\ncase \"$entry\" in *.html|*.htm) case \" $* \" in *' --outdir '*) ;; *) echo 'HTML entrypoint needs --outdir <dir>'; exit 2;; esac;; esac\ndeno bundle \"$entry\" \"$@\"","typeGuard":"function isHtmlEntrypoint(entry: string): boolean {\n  return /\\.(html|htm)$/i.test(entry);\n}","tryCatchPattern":null,"preventionTips":["Standardize build scripts on --outdir for all bundle targets","Remember HTML bundling is inherently multi-file (html/js/css/maps)"],"tags":["bundle","html","cli-flags","validation"],"backgroundTag":null,"analyzedSha":"89f33cbef296a2b287f323d42de54c871fa69c77","analyzedAt":"2026-08-16T07:54:21.310Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}