#10792·rolldown

[Bug]: Generated CJS wrapper collides with a source-declared local

Author: logaretmCreated Aug 28, 2026Updated Sep 17, 2026
Labelsp1: importantscope: correctness

Reproduction link or steps

https://repl.rolldown.rs/#eNp1U1Fr2zAQ/iuHKDiBVGlf3W0w0rwMVgbby0CwyPY5UStLniQnDSH/fSfLdpZuhUCsu/vu7vvu7sRqlp+YMhW+8uDjt2H55b1gJT2XS/ixQyit1qpSZgu10ghN5wMUCBIe19/WT4/rp9VPCDsZYIvBw+rL99uDk22L1QKMDeRCQBPckQtDGT97kCYZQFG8tqXUZHMIj6t1VpG36jF9Wa+sAYN7dFBb13jKoZrWugBaFVA724BgfEkPXj57wR6EEaa0xluNXNvtjDzzB+KDLA+uw/OCOcpb2YPhFFar7V/0/+NJQgwlT1BhrQyuejecU/1shGWxNr72oRQoO93/T4DZSRgAZdou5JBS8gaD5L1pASRO5B1F9uBRYxmwguLYW4suBJKCfijLHQRZxGStliHqkkNmbIXZIhptF/oSp14ySV8Z+iaDM3nPc2EYidDK8kVukT97S8wT/StbIt53LJiRDQqW09fI9dZh66xgfUHBaD5xUinmnt/xu8kVju2AbWzVafqmLlITcll1bZzb2MHFkMonMT3fS90hfIRMZg8RWLwFXgzvAIsEHPZkhI3Pad2/Kues83CI6zxyjWuKugZs4r6SpnHHc3D4u1MOb4cFjhpVsBmsvz4U0mO0fdqQEJT6oMKObmZz87QB39W1eqUqaCAcLCRlaOi7eAYSRizMdhgNI7v+Niau83RQm4TmA+cNqKH/F8TWQ2Gp7nhkWu2RHnTKaGy3pT2yw3kjJYt3Q7QHBlSFlBtes3hlUx+CzenQ/gm/uX8DmFpNAGGuW6XoE8hJyZgiTWwBxZX15n6Y5JmmSGPcx9nJgD6w8x+39KBe

Ran into this when testing out bundles produced by rolldown that get further bundled by rolldown downstream, cjs modules that have locals with a name can collide with the generated names causing:

Uncaught ReferenceError: Cannot access 'require_dup$1' before initialization

It seems to happen in that specific dependency shape.

What is expected?

The generated wrapper binding is deconflicted against the locals already declared in the source, and the bundle evaluates correctly.

What is actually happening?

The wrapper generated for b/dup.cjs takes the name require_dup$1, which the source already uses for its own local. Two things go wrong:

javascript
//#region a/dup.cjs
var require_dup$2 = /* @__PURE__ */ __commonJSMin(((exports) => {
    exports.value = "a";
}));
//#endregion
//#region index.ts
var import_lib = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
    const require_dup = require_dup$2();
    const require_dup$1 = require_dup$1();      // <- self-referencing
    module.exports = { a: require_dup.value, b: require_dup$1.value };
})))(), 1);
  1. the declaration is self-referencing, so it throws
  2. b/dup.cjs is not emitted at all - there is no region for it, and its wrapper definition is gone, so even the shadowing aside there is nothing left to call

System Info

bash
System:
    OS: macOS 26.5.2
    CPU: (12) arm64 Apple M3 Pro
    Memory: 806.73 MB / 36.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 24.12.0 - /Users/awad/.vite-plus/js_runtime/node/24.12.0/bin/node
    npm: 11.6.2 - /Users/awad/.vite-plus/js_runtime/node/24.12.0/bin/npm
    pnpm: 11.17.0 - /Users/awad/.volta/bin/pnpm
    bun: 1.4.0 - /Users/awad/.bun/bin/bun
    Deno: 2.8.0 - /Users/awad/.deno/bin/deno
    Watchman: 2026.07.20.00 - /opt/homebrew/bin/watchman
  Browsers:
    Brave Browser: 151.1.93.138
    Chrome: 152.0.7977.65
    Chrome Canary: 153.0.8010.0
    Firefox: 154.0.1
    Safari: 26.5.2
    Safari Technology Preview: 27.0

Any additional comments?

Similar to #9653, #9648, and #9721 but seems that this case has a different cause.

It seems rolldown cannot safely re-bundle its own CJS output, we hit this migrating the Sentry JavaScript SDK's package builds from rollup to rolldown. Our CJS output legitimately contains, in @sentry/core:

javascript
const require_public_api   = require("./logs/public-api.js");
const require_public_api$1 = require("./metrics/public-api.js");

An Astro 7 app (Vite 8) that inlines that package emits, which throws and makes the SDK crash user apps.

javascript
const require_public_api$1 = require_public_api$1();