The Rspack Build Completed. The Import Failed.
A targeted replay found the production-only defect that turned valid default imports into undefined at runtime.
Regression Case File | Open-source historical replay
Rspack v2.1.0 shipped with a production-only failure in CommonJS default exports. Development builds behaved normally. Production builds could replace a package’s real default export with undefined, leaving consumers to fail at runtime.
We deliberately selected the known regression window and replayed the changes between v2.1.0-rc.0 and v2.1.0. The final release contained 31 commits added after the release candidate. Early returned five findings. One was classified as a Regression, and it described the real export failure.
Independent historical replay. Not affiliated with Rspack.
The Failure
The public Rspack issue #14589 reported that local-storage-fallback worked in development but failed after a production build with Rspack v2.1.0. Its default import became undefined.
The affected package used a standard Babel-compiled CommonJS shape:
exports['default'] = void 0
var _default = (exports['default'] = value)
The first assignment initializes the export. The second assignment writes the real value. In v2.1.0, production optimization could discard that second write with an unused variable declaration. The emitted bundle kept the initial undefined value.
The production bundle still completed. Development still worked. The failure appeared when a consumer used the optimized output.
Release Timeline
The release candidate, v2.1.0-rc.0, shipped on June 23, 2026 and did not contain the regression. The introducing change merged on June 24. Rspack v2.1.0 shipped on June 26, and a user reported the failure 12 minutes later. The maintainers reverted the change in v2.1.1 on June 27.
The regression entered after the release candidate and remained in the final release for about 18 hours.
That sequence makes this a useful release-finalization case. It examines a specific decision: can a release owner comparing the approved RC with the final candidate see a harmful change before publishing the release?
How the Export Disappeared
The introducing PR #14260 changed how rspack_plugin_javascript reasons about side effects in CommonJS export assignments.
The optimization recognized the right-hand side as pure. It then treated the surrounding variable declaration as removable because the assigned variable was unused. That conclusion missed a separate effect inside the same expression: assigning the value to exports['default'].
Removing the unused declaration also removed the export write that consumers needed.
This was not a generic CommonJS failure. The reproduction required the chained assignment form shown above. A plain later reassignment did not trigger it. The failure also depended on production optimization, which explains why development could remain healthy.
The Historical Replay
The replay compared the rspack_plugin_javascript code in v2.1.0-rc.0 with v2.1.0. The stored run record lists seven changed files from that plugin, including the three source files changed by the introducing pull request.
Early returned five findings from the comparison:
| Verdict | Count | Independent review |
|---|---|---|
| Regression | 1 | The real CommonJS export defect |
| Expected | 4 | Not all independently verified as harmless |
The precision statement is deliberately narrow. The only Regression finding matched the known defect. There were no unmatched Regression findings. We did not independently establish that every Expected finding was harmless.
What Early Found
The finding was titled “CJS export-assign now DCE-prunable via declarator.” It identified the main culprit file and the newly added branch that treated the chained assignment as pure. It then followed the effect into production output: the export assignment could disappear and exports.default could remain at its initial undefined value.
The user-visible result was:
Early finding
“CJS export-assign now DCE-prunable via declarator”
Verdict: Regression

Actual Early product output from the historical replay. The finding and verdict are transcribed above for mobile readability.
The finding also proposed a concrete verification. Build a module with an observable load effect, reference it through an unused top-level CommonJS assignment, run a production build, and inspect both the emitted chunk and runtime output.
That stored procedure exercised the same faulty optimization path through a sibling CommonJS assignment. Our independent reproduction used the upstream Babel assignment shape and reached the same failure branch.
Verification and Limits
We ran an npm-only reproduction across four versions. Every production build command exited successfully.
The discriminating probe used the issue’s code in .js files. In our environment, the literal .cjs and .mjs file layout from the report returned a namespace object in every tested version, so it could not distinguish the regression boundary. The .js probe preserved the chained Babel assignment that triggered the faulty optimization and produced the clean version boundary below.
| Version | Result | Runtime output |
|---|---|---|
| v2.0.8 | Pass | RESULT:42 |
| v2.1.0-rc.0 | Pass | RESULT:42 |
| v2.1.0 | Fail | RESULT:undefined |
| v2.1.1 | Pass | RESULT:42 |
The clean boundary independently confirms the introducing and fixed releases. The v2.1.1 fix was a pure revert of PR #14260.
The introducing change merged after normal review activity and automated checks. Three reviewers commented, none recorded a formal approval, and two of 52 check runs failed. This case does not support a claim that the change passed every check. It shows that the production export failure remained in the final release despite the review and automation that took place.
The replay happened after the incident, and researchers selected the window because it contained a known regression. It is a case study, not an estimate of detection performance across arbitrary releases. Early did not participate in the original release, and this replay does not show that Early prevented it.
The supported conclusion is narrower. In the 31-commit comparison between the release candidate and final release, Early’s only Regression finding identified the real production export failure, its source mechanism, and a procedure for verifying the effect.
Reproduce and Verify
The case materials, including the release history, product output, and npm-only reproduction, are available by request. Contact us to request access.
With the materials, you can:
- Inspect the code and Git history between v2.1.0-rc.0 and v2.1.0.
- Compare Early’s finding with the introducing change and later upstream revert.
- Run the four-version reproduction and verify the pass, pass, fail, pass boundary.
The reproduction independently tests the runtime failure and fix. It does not rerun Regression Guard or recreate its proprietary analysis.
Sources and Method
Primary public sources include the user report, the RC-to-release comparison, the introducing pull request, the revert, and the fixed release comparison.
The historical replay ran on August 22, 2026. Human verification compared the product output with the release code, the executed reproduction, and the later upstream record.