Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

Debug ID changes the bytes of an optimized chunk but not its file name, so cached files fail the SRI check

Abierto
#34,574 0 comentarios 2 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

@alan-agius4 ya está trabajando en esto.

Desde el 29/10/2026.

  • #34583 de @alan-agius4 — abierto

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
55/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
angular, typescript
Área
build-system

Línea de trabajo

Start in execute-post-bundle.ts, where injectDebugIds changes output bytes, and chunk-optimizer.ts, where Rolldown assigns hashed chunk names. Trace how the chunk hash is computed and how debug IDs are injected, then check the build tests for optimized chunks and source maps. Done means a changed chunk byte sequence gets a different filename, including when only its source map changes.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

area: @angular/build
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

22.0.x

Description

Since 22.1.0 (#33110), the application builder adds a //# debugId=<uuid> line to each browser JS file when script source maps are enabled. The ID comes from the bytes of the source map.

When the chunk optimizer runs (by default when the build has 3 or more lazy chunks), Rolldown gives the chunks their final file names. The [hash] in these names covers the code of the chunk only. It does not cover the source map. The debugId line is added after that.

A change that keeps the JS code of a chunk the same but changes its source map (for example, a change to a TypeScript type or to a comment) gives this result for a chunk that does not import other chunks:

  1. The file name stays the same.
  2. The debugId changes, because the source map changed.
  3. The file bytes change, because the debugId line changed.
  4. The SRI hash in index.html changes to match the new bytes.

In one build, the HTML and the files match. Across two builds, the rule "same hashed file name means same content" is no longer true.

Hosting setups depend on this rule: they cache hashed files as immutable. Any cache can keep the file from the previous build: a CDN such as Cloudflare, the browser cache, or a proxy. That cache then serves the old bytes together with the new index.html. The integrity check fails, the browser blocks the file, and the modules in it do not load.

Before 22.1.0 there was no debugId line, so the bytes of a hashed file changed only when its name changed.

Expected behavior: if the bytes of a hashed output file change, its file name changes too.

Minimal Reproduction

Repository: https://github.com/virgiliojr/angular-debugid-sri-repro

The app is a plain ng new app (Angular CLI 22.2.2) with 3 lazy routes, so the chunk optimizer runs. lazy-a and lazy-b use src/app/shared/label.ts. This module has no imports, so it becomes its own chunk.

  1. Run npm ci.
  2. Run npx ng build --source-map --subresource-integrity.
  3. In dist/repro/browser/, find the chunk that contains label:. Write down its file name and its SHA-384.
  4. In src/app/shared/label.ts, add extra?: number; to the LabelInput interface. This is a type-only change: the JS output of label.ts stays the same.
  5. Run npx ng build --source-map --subresource-integrity again.
  6. Find the chunk that contains label: again.

bash compare-builds.sh in the repository does steps 2 to 6 and prints the result below.

Actual result:

Build 1
  file name:          chunk-z-ytF2G0.js
  sha384 of bytes:    sha384-Y7f5K4V0FTCrXc6JQ2tGE+VllRWg501EixeFEPMjNMboDgwfeRc9E6l8oHlqTbX5
  debugId line:       //# debugId=105cedd6-2603-584f-8e8d-7801d6020b96
  sha in index.html:  yes
Build 2
  file name:          chunk-z-ytF2G0.js
  sha384 of bytes:    sha384-bgCbCJmJexbhKCHeS4kpofe2lKBPWJ1f3JpK9668+/jD2mfiEYADUy5xD1Usr1dZ
  debugId line:       //# debugId=9c547775-c029-5af8-ba7e-25c70949f1b6
  sha in index.html:  yes

Diff of the chunk between the two builds:
2c2
< //# debugId=105cedd6-2603-584f-8e8d-7801d6020b96
---
> //# debugId=9c547775-c029-5af8-ba7e-25c70949f1b6

The file name is the same, but the bytes and the SRI hash in index.html are different.

Expected result: if the bytes are different, the file name is different too.

To see the failure in a browser, serve the output of build 2, but serve chunk-z-ytF2G0.js from build 1. This is what a cache does after a deployment.

Exception or Error
Failed to find a valid digest in the 'integrity' attribute for resource 'https://<host>/chunk-z-ytF2G0.js' with computed SHA-384 integrity '<hash>'. The resource has been blocked.
Your Environment
Angular CLI       : 22.2.5
Angular           : 22.2.3
Node.js           : 24.18.0
Package Manager   : npm 11.16.0
Operating System  : darwin arm64

┌───────────────────────────┬───────────────────┬───────────────────┐
│ Package                   │ Installed Version │ Requested Version │
├───────────────────────────┼───────────────────┼───────────────────┤
│ @angular/build            │ 22.2.5            │ ^22.2.2           │
│ @angular/cli              │ 22.2.5            │ ^22.2.2           │
│ @angular/common           │ 22.2.3            │ ^22.2.0           │
│ @angular/compiler         │ 22.2.3            │ ^22.2.0           │
│ @angular/compiler-cli     │ 22.2.3            │ ^22.2.0           │
│ @angular/core             │ 22.2.3            │ ^22.2.0           │
│ @angular/forms            │ 22.2.3            │ ^22.2.0           │
│ @angular/platform-browser │ 22.2.3            │ ^22.2.0           │
│ @angular/router           │ 22.2.3            │ ^22.2.0           │
│ rxjs                      │ 7.8.2             │ ~7.8.0            │
│ typescript                │ 6.0.3             │ ~6.0.2            │
└───────────────────────────┴───────────────────┴───────────────────┘
Anything else relevant?

This does not depend on the browser. Any cache in front of the hashed files can cause it.

The defect needs the chunk optimizer. With NG_BUILD_OPTIMIZE_CHUNKS=false, the same type change gives a new esbuild file name for the chunk (for example chunk-P54LQIKA.js to chunk-5HS55H7R.js), so the name and the bytes change together.

A chunk that imports other chunks usually gets a new name anyway, because the names of the chunks it imports change. A chunk without such imports keeps its name.

Related: #33108, #33110, #33572. The current main still has this behavior: injectDebugIds (called from execute-post-bundle.ts when sourcemapOptions.scripts is true) changes the file contents but does not change the file name. The Rolldown pass in chunk-optimizer.ts uses chunkFileNames: '<name>-[hash].js'.

Lenguaje dominante
TypeScript
Estrellas
27k
Forks
11.8k
Merge medio
1 d 5 h
PR fusionados (30 d)
276

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de angular/angular-cli

Todos los issues de angular/angular-cli

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.