oven-sh/bun · error · Error

Errors in ${entrypoint}: ${errors.map(x => x[1]).join("\n")}

Error message

Errors in ${entrypoint}:
${errors.map(x => x[1]).join("\n")}

What it means

After bundling a builtin module, the codegen scans the captured output for @bundleError(...) markers. These markers come from the $bundleError(...) compile-time intrinsic used in src/js sources (e.g. src/js/node/os.ts uses $bundleError("TODO: endianness")) to flag branches that must be eliminated during bundling. If a marker survives into the output, some branch of the module was left unimplemented or unreachable-code elimination could not prove it dead, so the build aborts listing every surviving marker.

Source

Thrown at src/codegen/bundle-modules.ts:279

        throw new Error(`Builtin Bundler: do not use import.meta.require() (in ${file_path}))`);
      })
      .replace(/return \$\nexport /, "return")
      .replace(/__intrinsic__/g, "@")
      .replace(/__no_intrinsic__/g, "") + "\n";
  captured = captured.replace(
    /function\s*\(.*?\)\s*{/,
    '$&"use strict";' +
      (usesDebug
        ? createLogClientJS(
            file_path.replace(".js", ""),
            idToPublicSpecifierOrEnumName(file_path).replace(/^node:|^bun:/, ""),
          )
        : "") +
      (usesAssert ? createAssertClientJS(idToPublicSpecifierOrEnumName(file_path).replace(/^node:|^bun:/, "")) : ""),
  );
  const errors = [...captured.matchAll(/@bundleError\((.*)\)/g)];
  if (errors.length) {
    throw new Error(`Errors in ${entrypoint}:\n${errors.map(x => x[1]).join("\n")}`);
  }

  const outputPath = path.join(JS_DIR, file_path);
  fs.mkdirSync(path.dirname(outputPath), { recursive: true });
  fs.writeFileSync(outputPath, captured);
  outputs.set(file_path.replace(".js", ""), captured);
}

mark("Postprocesss modules");

/**
 * Physical layout order for the module-source blob: DFS post-order over the
 * static require() graph, so each module sits contiguous with its transitive
 * dependencies. Loading any builtin then reads one contiguous run of pages
 * instead of touching sources scattered across the blob. Roots are visited in
 * a fixed order (the popular entry modules first) so the layout is
 * deterministic; the graph over-approximates lazy requires, which only makes
 * neighbours of things that *might* co-load — free for layout.

View on GitHub (pinned to 8c5296ac45)

Solutions

  1. Read the listed marker messages — they are exactly the $bundleError strings that survived (e.g. 'TODO: endianness') and identify the unimplemented case
  2. Implement the missing branch so $bundleError becomes unreachable, or make its condition statically known to the bundler
  3. Re-run the codegen to confirm no markers remain in the module output

Example fix

// before (builtin module)
process.arch === "x64" ? "x64" : $bundleError("TODO: arch");

// after
process.arch === "x64" ? "x64" : "unknown";
Defensive patterns

Strategy: validation

Validate before calling

// scan builtin sources for $bundleError placeholders before building
import { Glob } from "bun";
for (const f of new Glob("src/js/**/*.{ts,js}").scanSync(".")) {
  const text = await Bun.file(f).text();
  if (text.includes("$bundleError")) {
    console.warn(`${f} still contains $bundleError — ensure every branch is bundle-time resolvable`);
  }
}

Prevention

When it happens

Trigger: Adding a $bundleError(...) to a new branch of a builtin module and that branch survives bundling (the surrounding condition is not statically resolvable at bundle time); or editing conditional logic in a module like src/js/node/os.ts so a previously dead $bundleError branch becomes reachable.

Common situations: Contributors stubbing out a platform-specific case with $bundleError as a placeholder; build-time defines changing so a previously eliminated branch no longer constant-folds.

Related errors


AI-assisted analysis of oven-sh/bun@8c5296ac45 (2026-08-16). Data as JSON: /api/errors/e6b139c0f2ea6ab0. Report an issue: GitHub.