denoland/deno · error · anyhow::Error

Deno.bundle() is not available in compiled binaries (`deno…

Error message

Deno.bundle() is not available in compiled binaries (`deno compile`). Run with `deno run` instead, or pre-bundle the entrypoints at build time.

What it means

Deno.bundle() needs the compiler/bundler machinery that only the full CLI wires up. Compiled binaries produced by `deno compile` use the denort runtime, which registers the no-op BundleProvider for `()` (ext/bundle/src/lib.rs:43-56); calling Deno.bundle() there surfaces this explicit error — a deliberate improvement over the old "default BundleProvider does not do anything" string (denoland/deno#31597).

Solutions

  1. Run the program with `deno run` when it needs to bundle.
  2. Pre-bundle entrypoints at build time (before deno compile) and embed/ship the emitted files instead of bundling at runtime.
  3. Feature-detect and degrade gracefully: guard the call and emit a clear message when running inside a compiled binary.

Example fix

// before
const result = await Deno.bundle(entry);   // throws inside `deno compile` output

// after — pre-bundle at build time and embed
deno eval 'const r = await Deno.bundle("./src/entry.ts"); await Deno.writeTextFile("dist/bundle.json", JSON.stringify(r));'
// then in the compiled app, read the embedded dist/bundle.json instead of calling Deno.bundle()
Defensive patterns

Strategy: fallback

Validate before calling

// Detect a compiled binary before attempting to bundle at runtime
const isCompiled = Deno.execPath().endsWith(Deno.mainModule.replace(/^.*\//, "")) === false
  || !(await Deno.stat(Deno.mainModule.replace("file://", "")).catch(() => null));

Prevention

When it happens

Trigger: Compiling an app with `deno compile -o app main.ts` whose code path calls Deno.bundle(...); bundling-on-demand logic that works under `deno run` but ships inside a compiled executable.

Common situations: CLI tools that offer a `bundle` subcommand by calling Deno.bundle at runtime; pipelines ported from `deno bundle`; feature-detecting code that assumed the API exists everywhere.

Related errors


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

Appendix: source

Thrown at ext/bundle/src/lib.rs:52

    } else {
      state.put::<Arc<dyn BundleProvider>>(Arc::new(()));
    }
  },
);

#[async_trait]
impl BundleProvider for () {
  async fn bundle(
    &self,
    _options: BundleOptions,
    _permissions: PermissionsContainer,
  ) -> Result<BuildResponse, AnyError> {
    // Embedders that don't wire up a real provider (notably `denort`, used
    // by `deno compile` outputs) fall through to this no-op implementation.
    // Surface that limitation directly to the user instead of leaking the
    // historical "default BundleProvider does not do anything" string.
    // See denoland/deno#31597.
    Err(deno_core::anyhow::anyhow!(
      "Deno.bundle() is not available in compiled binaries (`deno compile`). \
       Run with `deno run` instead, or pre-bundle the entrypoints at build time."
    ))
  }
}

#[async_trait]
pub trait BundleProvider: Send + Sync {
  async fn bundle(
    &self,
    options: BundleOptions,
    permissions: PermissionsContainer,
  ) -> Result<BuildResponse, AnyError>;
}

#[derive(Clone, Debug, Eq, PartialEq, Default, FromV8)]
pub struct BundleOptions {
  pub entrypoints: Vec<String>,

View on GitHub (pinned to 9ad36f7a2c)