angular-cli icon indicating copy to clipboard operation
angular-cli copied to clipboard

Heap corruption error on windows when createCompilerPlugin is called before serveWithVite

Open Aukevanoost opened this issue 1 month ago • 4 comments

Command

build, serve

Is this a regression?

  • [x] Yes, this behavior used to work in the previous version

The previous version in which this bug was not present was

v19.x

Description

Ok so this is a complex one, I've already lost a couple of days on this.

Native federation is using the "createCompilerPlugin" to create reusable artifacts (read dependencies) to be used in the Angular application. Now we know this is kind of an "own risk" scenario, especially since it's in the private folder of the @angular/build package but I am slowly losing it.

Some context When we do "ng serve" on our own builder, which is basically a wrapper around the default angular build, we use ESbuild to build some packages that we want to re-use across Angular micro frontends. The code can be found in our esbuild-adapter.ts and our builder.ts. The interesting part is that we don't get an error when we remove the AngularCompilerPlugin which we use to pre-build our artifacts.

The error Since Angular 20, we have the issue that during the serveWithVite and to be precise in the line where vite is imported., an heap error occurs. We thought it could be ESbuild since it's also used in the vite package, but all our tries have been without result so far.

Whe have an issue with all the context. Note: that all assumptions so far were wrong. Even after ng21, the issue still persists. I thought it was a race condition when closing/disposing the compiler-plugin but this is not the case.

Now I know micro frontends and using the private part of the @angular/build is for our own risk, but I would never expect a heap error. Does anyone know how this could happen or what could cause this? Final note: It is a race condition so it happens every now and then, about 40% of the ng serve builds. It happens only on windows and you can recognize the error by the build/serve just stopping without any error.

All help is welcome, thanks a bunch in advance.

Minimal Reproduction

We have a reproducable repo: https://github.com/berkon/ng-serve-crash-reproduction (it also crashes when you update to ng21).

just npm ci and npm start. Even updating to ng21 doesn't help

Exception or Error

Process finished with exit code -1073740940 (0xC0000374)

Your Environment

Just windows 10+, reest can be seen in the repository

Anything else relevant?

No response

Aukevanoost avatar Nov 28 '25 15:11 Aukevanoost

Let me know if you need anymore context/explanation

Aukevanoost avatar Nov 28 '25 15:11 Aukevanoost

Since this is a heap corruption, can you also include which node versions you tried? Usually JS code triggering heap issues is a VM bug (native plugins aside).

hybrist avatar Nov 28 '25 17:11 hybrist

I tried with v22.21.1 and v24.11.1 but no luck so far.

edit: My gut feeling is that the corruption happens in ESbuild but I can't proof it yet.

Aukevanoost avatar Nov 28 '25 18:11 Aukevanoost

@Aukevanoost Not sure if it's a fix, but you may find this comment useful.

albertalvin8080 avatar Dec 03 '25 17:12 albertalvin8080

Unfortunately it's not. My gut feeling is that it's because the workerpool has not been closed correctly in the ParallelCompiler when the serveWithVite starts. Can anyone confirm if this could lead to a memory corruption? I feel that since this is a fire-and-forget call, we can't wait for the workers to be cleaned up correctly before starting the vite server.

Aukevanoost avatar Dec 05 '25 13:12 Aukevanoost

@Aukevanoost, if you do not use the parallel worker do you still get the heap corruption error? You can disable this by setting the env variable NG_BUILD_PARALLEL_TS=0

alan-agius4 avatar Dec 08 '25 13:12 alan-agius4

Yes, that unfortunately doesn't seem to fix it. I went a bit deeper in the vite package and apparently it happens in the

node_modules/vite/dist/node/chunks/config.js 

at the line:

import { parseAst, parseAstAsync } from "rollup/parseAst";

Now I figured out where the crash is happening and it's because rollup tries to access corrupted memory here:

https://github.com/rollup/rollup/blob/c5f3e1d3162ccb36e18704138c21457a084ef358/native.js#L15C1-L15C68

const { platform, arch, report } = require('node:process');
return report.getReport().header.osName.startsWith('MINGW32_NT');

A little bit of googling around tells me that the Report returns the current state of the node process (which is probably broken). I still don't know where the node process get's corrupted.

Aukevanoost avatar Dec 08 '25 19:12 Aukevanoost

Looks like the upstream issue has been resolved.

alan-agius4 avatar Dec 16 '25 11:12 alan-agius4