Skip to content

ng build hangs after a successful build on @angular/build 21.2.14–21.2.18 (regression from #33267) #33497

Closed

Description

@hskiba

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

21.2.13

Description

ng build (no --watch) finishes successfully. It prints the build summary and "Output location," then the process never exits. A lingering esbuild --service=<version> --ping child stays alive next to the still-running ng build parent, and both have to be killed by hand.

This looks like a regression from #33267 (merged in 21.2.14), which switched one-shot builds from a plain esbuild.build() call to esbuild.context() + .rebuild(), the persistent-IPC path normally reserved for watch mode. That PR fixed a real leak (#33201), but seems to have opened a scheduling/teardown race for one-shot builds instead.

This was already filed as #33480 and closed for lack of a reproducible case. I put together a minimal repro from scratch to close that gap.

Minimal Reproduction

Repo: https://github.com/hskiba/ng-build-hang-repro

git clone https://github.com/hskiba/ng-build-hang-repro
cd ng-build-hang-repro
npm install
npx ng build

The build finishes, then hangs. ps aux | grep esbuild in another terminal shows the stuck service process.

Three commits show exactly what triggers it:

  1. initial commit: untouched ng new output, builds and exits fine
  2. Add minimal trigger...: adds one file with two trivial @Component classes, each with nothing but an inline styles: block. It's never imported or routed anywhere, only picked up via tsconfig.app.json's include: ["src/**/*.ts"]. Adding it alone causes the hang.
  3. Document root cause...: full writeup

What I found bisecting it: the count of components with inline styles: blocks is what matters. Two hangs it, one doesn't. CSS content is irrelevant, a bare :host { display: block; } triggers it just as reliably as anything more elaborate. Host bindings, signals, file size, and third-party dependencies are all beside the point. Pinning to 21.2.13 with the identical source file builds and exits cleanly.

Exception or Error

none (never exits)

Your Environment

Angular CLI       : 21.2.18
Angular           : 21.2.17
Node.js           : 24.18.0
Package Manager   : npm 11.16.0
Operating System  : darwin arm64

@angular/build            21.2.18
@angular/cli              21.2.18
@angular/common           21.2.17
@angular/compiler          21.2.17
@angular/compiler-cli      21.2.17
@angular/core              21.2.17
@angular/forms             21.2.17
@angular/platform-browser  21.2.17
@angular/router            21.2.17
rxjs                       7.8.2
typescript                 5.9.3
vitest                     4.1.9

Anything else relevant?

Reproduced on macOS (arm64) and was happening in our container builds for both arm64 and amd64.

Activity

  1. added this to the needsTriage milestone on Jul 1, 2026
  2. jussik commented on Jul 2, 2026

    @jussik

    We hit the same issue, it triggers when you have multiple identical styles in the same file because it generates the same cache keys based on language+sha256(styleContent)+filename in ComponentStylesheetBundler.

  3. isms-core-project commented on Jul 2, 2026

    @isms-core-project

    Filed the earlier report on this regression as #33480 (closed for lack of a minimal repro — apologies, should have led with one). Your repro here nails the actual trigger far more precisely than we did.

    For what it's worth, our data point: we hit this specifically inside docker compose build on a Linux host (Debian/Alpine node:22-slim), where it manifested as a hard hang with all worker threads parked in Atomics.wait() and 0% CPU — 8 to 20 minutes before we gave up and killed it, never an error. We initially attributed it to Docker/Linux IPC pipe timing around esbuild.context(), since that matched what we could observe from the outside. Your bisection (identical inline styles: cache-key collision in ComponentStylesheetBundler, reproducible on bare macOS arm64 too) is the real mechanism — the Docker environment we were building in just happened to be where we noticed it, not the cause.

    Confirms this isn't an isolated/environmental issue. Pinning @angular/build/@angular/cli to 21.2.12–21.2.13 is our workaround until this lands a fix.

  4. alan-agius4 commented on Jul 6, 2026

    @alan-agius4
    Collaborator
  5. hskiba commented on Aug 5, 2026

    @hskiba
    Author

    Closed via https://github.com/angular/angular-cli/pulls

    Are there plans to backport this to 21.x?

  6. alan-agius4 commented on Aug 5, 2026

    @alan-agius4
    Collaborator

    Version 21 is now an LTS release, with backports restricted strictly to security fixes.

  7. angular-automatic-lock-bot commented on Oct 18, 2026

    @angular-automatic-lock-bot

    This issue has been automatically locked due to inactivity.
    Please file a new issue if you are encountering a similar or related problem.

    Read more about our automatic conversation locking policy.

    This action has been performed automatically by a bot.

  8. locked and limited conversation to collaborators on Oct 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions