Command
build
Is this a regression?
- Yes, this behavior used to work in the previous version
The previous version in which this bug was not present was
Unconfirmed - likely any version prior to the oxc-transform.js rewrite introduced around 22.1.0 (same regression window as #33699).
Description
This is related to #33699, fixed by #33700, but appears to be a broader/different bug that isn't fully resolved by that fix.
src/tools/babel/plugins/oxc-transform.js performs single-pass AST-based source rewriting via oxc-parser + magic-string, wrapping TypeScript-emitted enums (adjustTypeScriptEnumsInStatements) and Angular/class static members (adjustStaticMembersInStatements) into pure IIFEs for tree-shaking. #33699 found an appendLeft/appendRight ordering bug in the latter function for adjacent minified classes, fixed by swapping the insertion order in #33700.
I hit a similar-looking corruption (Unexpected "}" at the closing })(); of a wrapped statement) in two unrelated vendor files consistently, on every build, but only on our GitLab CI's native x86_64 Docker runners - never locally (Apple Silicon via Rosetta-emulated x86_64 Docker, using the byte-for-byte identical image/lockfile/node_modules, verified via SHA-256 checksum).
I bisected my own working fix down via bun patch on @angular/build@22.1.6 (which already includes the #33700 fix) and found:
- Disabling both adjustTypeScriptEnumsInStatements and adjustStaticMembersInStatements (short-circuiting each to a no-op) + forcing atomics: 'disabled' in src/utils/worker-pool.js's Piscina options (instead of the default 'sync') → build passes reliably.
- Re-enabling only adjustStaticMembersInStatements (leaving the enum function disabled, atomics still disabled) → build fails again, even though this function already contains the fix(@angular/build): prevent IIFE wrapper interleaving for adjacent classes in minified files #33700 fix (confirmed: the installed 22.1.6 source has the appendRight(classNode.start, ...)/appendLeft(lastStatement.end, ...) ordering from that PR). This suggests fix(@angular/build): prevent IIFE wrapper interleaving for adjacent classes in minified files #33700 does not cover every code path in this function - possibly the __decorate-wrapping or elision branches, which weren't touched by that PR's diff.
- Removing only the atomics: 'disabled' change (keeping both functions disabled) → build fails again. This was surprising since we assumed the text-splicing bug should be purely deterministic/input-dependent, unrelated to worker thread synchronization. This suggests either a genuine concurrency element (e.g. stale/cross-contaminated state between files processed by the same reused worker thread, only exposed under certain Atomics.wait/futex timing), or that the 'sync' atomics mode itself interacts with the native oxc-parser binding in a way that produces incorrect AST offsets under specific scheduling conditions.
I am not able to fully isolate a single minimal cause - only the combination of all three changes together reliably fixes it. I was also unable to produce a minimal public repro (a fresh ng new + npm i quill@2.0.3 did not reproduce it standalone, even on the failing CI environment) - my repro requires my full app (which includes a private package, and quill), built on a real native x86_64 GitLab CI Docker runner.
Minimal Reproduction
Not available as a minimal public repro (see above). Happy to test candidate fixes/diagnostics against our real CI pipeline, since I can reproduce this with 100% reliability there.
Failing file/line (consistent across every run):
- node_modules/parchment/dist/parchment.js:86:0
Third-party pre-built ESM/CJS bundles consistent with #33699's observation that this only affects pre-built vendor code (Angular's own non-minified fesm2022 packages are unaffected).
Exception or Error
✘ [ERROR] Unexpected "}"
node_modules/parchment/dist/parchment.js:86:0:
86 │ })();
╵ ^
Your Environment
Angular CLI: 22.1.6
@angular/build: 22.1.6
@angular/core: 22.1.4
oxc-parser: 0.142.0
rolldown: 1.2.0
piscina: 5.2.0
Package Manager: bun 1.4.0
OS (failing, 100% reproducible): Alpine Linux 3.23, linux/x86_64, native (confirmed no QEMU/binfmt emulation, `cgroup cpu.max`: unlimited, `memory.max`: 32GiB)
OS (never fails): macOS (Apple Silicon, arm64), Docker Desktop, linux/amd64 image run via Rosetta 2 emulation
Angular: 22.1.4 (ivy)
Anything else relevant?
My current working mitigation (applied via bun patch), for reference:
for (...) { ... }
return; // disabled
for (...) { ... }
@@ function adjustStaticMembersInStatements(body) {
for (...) { ... }
return; // disabled
for (...) { ... }
--- a/src/utils/worker-pool.js +++ b/src/utils/worker-pool.js
atomics: process.versions.webcontainer ? 'disabled' : 'sync',
atomics: 'disabled', ```
This trades away some tree-shaking of enums/class-statics for the vendor files I ship, but restores a reliable production build. I'd very much like a proper fix so we can re-enable full advancedOptimizations.
This version is honest about the fact that I couldn't cleanly isolate a single cause — which is itself useful signal (it points toward either an incomplete fix in #33700, or a genuine worker-concurrency interaction, rather than a simple one-line bug). Want me to also open a note in my own repo (e.g. a KNOWN_ISSUES.md or a comment near the patch file) documenting this so future maintainers understand why the patch exists and when it might be safe to remove?
Command
build
Is this a regression?
The previous version in which this bug was not present was
Unconfirmed - likely any version prior to the oxc-transform.js rewrite introduced around 22.1.0 (same regression window as #33699).
Description
This is related to #33699, fixed by #33700, but appears to be a broader/different bug that isn't fully resolved by that fix.
src/tools/babel/plugins/oxc-transform.js performs single-pass AST-based source rewriting via oxc-parser + magic-string, wrapping TypeScript-emitted enums (adjustTypeScriptEnumsInStatements) and Angular/class static members (adjustStaticMembersInStatements) into pure IIFEs for tree-shaking. #33699 found an appendLeft/appendRight ordering bug in the latter function for adjacent minified classes, fixed by swapping the insertion order in #33700.
I hit a similar-looking corruption (Unexpected "}" at the closing })(); of a wrapped statement) in two unrelated vendor files consistently, on every build, but only on our GitLab CI's native x86_64 Docker runners - never locally (Apple Silicon via Rosetta-emulated x86_64 Docker, using the byte-for-byte identical image/lockfile/node_modules, verified via SHA-256 checksum).
I bisected my own working fix down via bun patch on @angular/build@22.1.6 (which already includes the #33700 fix) and found:
I am not able to fully isolate a single minimal cause - only the combination of all three changes together reliably fixes it. I was also unable to produce a minimal public repro (a fresh ng new + npm i quill@2.0.3 did not reproduce it standalone, even on the failing CI environment) - my repro requires my full app (which includes a private package, and quill), built on a real native x86_64 GitLab CI Docker runner.
Minimal Reproduction
Not available as a minimal public repro (see above). Happy to test candidate fixes/diagnostics against our real CI pipeline, since I can reproduce this with 100% reliability there.
Failing file/line (consistent across every run):
Third-party pre-built ESM/CJS bundles consistent with #33699's observation that this only affects pre-built vendor code (Angular's own non-minified fesm2022 packages are unaffected).
Exception or Error
✘ [ERROR] Unexpected "}" node_modules/parchment/dist/parchment.js:86:0: 86 │ })(); ╵ ^Your Environment
Anything else relevant?
My current working mitigation (applied via bun patch), for reference:
for (...) { ... } return; // disabled for (...) { ... } @@ function adjustStaticMembersInStatements(body) { for (...) { ... } return; // disabled for (...) { ... } --- a/src/utils/worker-pool.js +++ b/src/utils/worker-pool.js atomics: process.versions.webcontainer ? 'disabled' : 'sync', atomics: 'disabled', ``` This trades away some tree-shaking of enums/class-statics for the vendor files I ship, but restores a reliable production build. I'd very much like a proper fix so we can re-enable full advancedOptimizations.This version is honest about the fact that I couldn't cleanly isolate a single cause — which is itself useful signal (it points toward either an incomplete fix in #33700, or a genuine worker-concurrency interaction, rather than a simple one-line bug). Want me to also open a note in my own repo (e.g. a KNOWN_ISSUES.md or a comment near the patch file) documenting this so future maintainers understand why the patch exists and when it might be safe to remove?