Command
test
Is this a regression?
The previous version in which this bug was not present was
22.1.4
Description
@angular/build:unit-test (vitest runner) reliably kills the esbuild service during the build phase on a 2-CPU / 7 GB machine — the shape of a private-repo ubuntu-latest GitHub Actions runner. The identical suite builds and runs fine on 22.1.4.
It fails before any test executes, so this is not a test-isolation or teardown problem.
Version bisection (2×2). Our project moved the Angular framework and the builder in one commit, so both were tested independently. Each cell is the identical suite (210 spec files / 3364 tests) in the identical container:
@angular/core |
@angular/build + @angular/cli |
result |
| 22.1.2 |
22.1.4 |
builds, whole suite runs |
| 22.1.3 |
22.1.4 |
builds, whole suite runs |
| 22.1.2 |
22.1.5 |
build dies — "The service was stopped" |
| 22.1.3 |
22.1.5 |
build dies — same |
@angular/build 22.1.5 is necessary and sufficient; the framework version is irrelevant.
Already ruled out, so as not to waste triage time:
- Not the Node heap.
NODE_OPTIONS=--max-old-space-size=4096 changes nothing. The victim is esbuild's separate service process, not V8.
- Not (visibly) the kernel OOM killer. On GitHub Actions the job dies with
SIGTERM (143); there is no exit 137 in any run, and 137/SIGKILL is what a cgroup OOM kill looks like.
- Not test isolation.
--isolate=true does not help. It cannot — the failure precedes test execution.
- Not visible on a developer machine. The full suite is green locally on both 22.1.4 and 22.1.5 on a many-core box. Only the constrained machine shows it, which is why it reached us as a CI-only failure.
Minimal Reproduction
No public reproduction repository yet — I could not reduce it to ng new plus a handful of specs, because the failure appears to need a substantial spec set and does not occur on an unconstrained machine. What I can offer instead is a reproduction that needs no CI account and takes ~57 seconds, from any existing Angular workspace using @angular/build:unit-test:
# from the workspace root, with @angular/build + @angular/cli at 22.1.5
docker run --rm --cpus=2 --memory=7g --memory-swap=7g \
-v "$PWD":/app -w /app node:24 \
bash -lc 'corepack enable && pnpm install --frozen-lockfile && pnpm exec ng test --watch=false'
Steps:
- Run the above. The build fails with
The service was stopped (see below).
- Change only
@angular/build and @angular/cli to 22.1.4, reinstall, run again. The build succeeds and the suite runs to completion.
- Change only
@angular/core and its siblings between 22.1.2 and 22.1.3 with the builder pinned either way — no effect on the outcome.
--cpus=2 --memory=7g is load-bearing: the failure does not appear without the constraint.
Our workspace passes runnerConfig, but its contents are an empty defineConfig({}), so no project-level vitest tuning is involved.
If a public repro repository is required to action this, I am glad to build one — please say whether you would prefer a generated workspace with N synthetic specs, and roughly what N you would consider acceptable. The bisect loop is under a minute here, so additional data points are cheap; I am happy to run any experiment you would find useful.
Exception or Error
Using Vitest configuration file: /app/vitest-base.config.ts
❯ Building...
✖ Building... [FAILED: The service was stopped]
An exception occurred while creating the test executor:
Error: The service was stopped
at /app/node_modules/.pnpm/esbuild@0.28.2/node_modules/esbuild/lib/main.js:1259:26
at responseCallbacks.<computed> (/app/node_modules/.pnpm/esbuild@0.28.2/node_modules/esbuild/lib/main.js:886:9)
at Socket.afterClose (/app/node_modules/.pnpm/esbuild@0.28.2/node_modules/esbuild/lib/main.js:877:28)
at Socket.emit (node:events:521:24)
at endReadableNT (node:internal/streams/readable:1736:12)
at process.processTicksAndRejections (node:internal/process/task_queues:90:21)
On GitHub Actions the same regression surfaces far less legibly — twice on the same commit:
# run 1 — died 67s in, during the build, before any test
12:09:02 ❯ Building...
12:10:09 undefined
12:10:09 [ERR_PNPM_RECURSIVE_EXEC_FIRST_FAIL] Command was killed with SIGTERM (Termination): ng test '--watch=false'
12:10:09 ##[error]The operation was canceled.
# run 2 — same commit, re-run: tests ran and PASSED, then 63s of silence
12:26:04 ✓ src/app/shared/components/cfm-form/cfm-form-validators.spec.ts (89 tests)
12:27:07 ##[error]The operation was canceled.
The bare undefined in run 1 appears to be the parent trying to log an error object from a child that was already gone.
Your Environment
Angular CLI : 22.1.4 <-- works; 22.1.5 fails
Angular : 22.1.3 <-- not the variable; 22.1.2 behaves identically
Node.js : 24.19.0
Package Manager : pnpm 11.22.0
Operating System : win32 x64 (local, passes) / linux x64 container, 2 CPU / 7 GB (fails)
┌───────────────────────────┬───────────────────┬───────────────────┐
│ Package │ Installed Version │ Requested Version │
├───────────────────────────┼───────────────────┼───────────────────┤
│ @angular/build │ 22.1.4 │ 22.1.4 │
│ @angular/cdk │ 22.1.3 │ 22.1.3 │
│ @angular/cli │ 22.1.4 │ 22.1.4 │
│ @angular/common │ 22.1.3 │ 22.1.3 │
│ @angular/compiler │ 22.1.3 │ 22.1.3 │
│ @angular/compiler-cli │ 22.1.3 │ 22.1.3 │
│ @angular/core │ 22.1.3 │ 22.1.3 │
│ @angular/forms │ 22.1.3 │ 22.1.3 │
│ @angular/language-service │ 22.1.3 │ 22.1.3 │
│ @angular/material │ 22.1.3 │ 22.1.3 │
│ @angular/platform-browser │ 22.1.3 │ 22.1.3 │
│ @angular/router │ 22.1.3 │ 22.1.3 │
│ @angular/service-worker │ 22.1.3 │ 22.1.3 │
│ rxjs │ 7.8.2 │ ^7.8.2 │
│ typescript │ 6.0.3 │ ~6.0.3 │
│ vitest │ 4.1.11 │ ^4.1.11 │
│ zone.js │ 0.16.2 │ ^0.16.2 │
└───────────────────────────┴───────────────────┴───────────────────┘
esbuild 0.28.2 (transitive)
Suite size: 210 spec files, 3364 tests
Anything else relevant?
I searched open and closed issues first. Closest matches, none of which report this as a 22.1.4 → 22.1.5 regression:
Package manager is pnpm, which puts esbuild's binary under node_modules/.pnpm/…; I have not tested whether npm or yarn behave differently.
Command
test
Is this a regression?
The previous version in which this bug was not present was
22.1.4
Description
@angular/build:unit-test(vitest runner) reliably kills the esbuild service during the build phase on a 2-CPU / 7 GB machine — the shape of a private-repoubuntu-latestGitHub Actions runner. The identical suite builds and runs fine on 22.1.4.It fails before any test executes, so this is not a test-isolation or teardown problem.
Version bisection (2×2). Our project moved the Angular framework and the builder in one commit, so both were tested independently. Each cell is the identical suite (210 spec files / 3364 tests) in the identical container:
@angular/core@angular/build+@angular/cli@angular/build22.1.5 is necessary and sufficient; the framework version is irrelevant.Already ruled out, so as not to waste triage time:
NODE_OPTIONS=--max-old-space-size=4096changes nothing. The victim is esbuild's separate service process, not V8.SIGTERM(143); there is no exit 137 in any run, and 137/SIGKILLis what a cgroup OOM kill looks like.--isolate=truedoes not help. It cannot — the failure precedes test execution.Minimal Reproduction
No public reproduction repository yet — I could not reduce it to
ng newplus a handful of specs, because the failure appears to need a substantial spec set and does not occur on an unconstrained machine. What I can offer instead is a reproduction that needs no CI account and takes ~57 seconds, from any existing Angular workspace using@angular/build:unit-test:Steps:
The service was stopped(see below).@angular/buildand@angular/clito22.1.4, reinstall, run again. The build succeeds and the suite runs to completion.@angular/coreand its siblings between22.1.2and22.1.3with the builder pinned either way — no effect on the outcome.--cpus=2 --memory=7gis load-bearing: the failure does not appear without the constraint.Our workspace passes
runnerConfig, but its contents are an emptydefineConfig({}), so no project-level vitest tuning is involved.If a public repro repository is required to action this, I am glad to build one — please say whether you would prefer a generated workspace with N synthetic specs, and roughly what N you would consider acceptable. The bisect loop is under a minute here, so additional data points are cheap; I am happy to run any experiment you would find useful.
Exception or Error
On GitHub Actions the same regression surfaces far less legibly — twice on the same commit:
The bare
undefinedin run 1 appears to be the parent trying to log an error object from a child that was already gone.Your Environment
Anything else relevant?
I searched open and closed issues first. Closest matches, none of which report this as a 22.1.4 → 22.1.5 regression:
The service was stoppederror, but on much older CLI versions and centred on Windows / Node 22.@angular/build:unit-testvirtualinit-testbed.jsguardsinitTestEnvironment()behind a once-per-worker symbol → stale DomAdapter under vitest ≥4.0.5 +isolate: false#33047 and unit-test (vitest): isolate:false default silently breaks cross-file vi.mock() of shared modules on low-CPU workers #33570 concernisolate: falseand low-CPU workers. They look like a different bug in the same neighbourhood —--isolate=truehas no effect on the failure reported here, which occurs before tests run.Package manager is pnpm, which puts esbuild's binary under
node_modules/.pnpm/…; I have not tested whether npm or yarn behave differently.