angular/angular-cli · warning
[NG HMR] Cannot find global 'ng'. Likely this is caused beca
Error message
[NG HMR] Cannot find global 'ng'. Likely this is caused because scripts optimization is enabled.
What it means
During Hot Module Replacement the HMR dispose callback (registered in hmr-accept.ts) checks for the Angular testing/global helper object 'ng' in the window scope. When scripts optimization is enabled, the UMD chunks that define the global 'ng' are minified/scope-isolated so the global no longer exists; HMR then logs this warning and aborts the dispose step because it cannot call ng.ɵɵhmr helper APIs.
Source
Thrown at packages/angular_devkit/build_angular/src/tools/webpack/plugins/hmr/hmr-accept.ts:47
declare const Event: any;
export default function (mod: any): void {
if (!mod['hot']) {
return;
}
if (!isDevMode()) {
console.error(
`[NG HMR] Cannot use HMR when Angular is running in production mode. To prevent production mode, do not call 'enableProdMode()'.`,
);
return;
}
mod['hot'].accept();
mod['hot'].dispose(() => {
if (typeof ng === 'undefined') {
console.warn(
`[NG HMR] Cannot find global 'ng'. Likely this is caused because scripts optimization is enabled.`,
);
return;
}
if (!ng.getInjector) {
// View Engine
return;
}
// Reset JIT compiled components cache
ɵresetCompiledComponents();
const appRoot = getAppRoot();
if (!appRoot) {
return;
}
View on GitHub (pinned to bb72145f9a)
Solutions
- Disable scripts optimization in the serve configuration: "optimization": { "scripts": false, "styles": true } under configurations/development (or serve options).
- Serve with the development configuration: ng serve --configuration development.
- If you intentionally optimize scripts, accept that HMR dispose is degraded — this warning is non-fatal; do a full reload instead of relying on HMR state preservation.
- Verify the ng global exists at runtime by checking window.ng in devtools; if absent while serving unoptimized, check for scripts that shadow/delete the global.
Example fix
// before (angular.json, serve configuration)
"optimization": true
// => [NG HMR] Cannot find global 'ng'.
// after
"configurations": {
"development": {
"optimization": false,
"hmr": true
}
}
// ng serve --configuration development Defensive patterns
Strategy: fallback
Validate before calling
// In the app, verify the ng global exists before relying on HMR state preservation
function hmrViable() {
return typeof ng !== 'undefined';
}
if (!hmrViable()) {
console.warn('[NG HMR] global ng missing (scripts optimization on?) — full reload will be used instead of HMR.');
} Type guard
function hasNgGlobal(win = window) {
return typeof win['ng'] !== 'undefined';
} Try / catch
try {
// HMR update flow
module.hot.dispose(() => { if (typeof ng === 'undefined') { location.reload(); return; } /* normal dispose */ });
} catch (e) {
console.warn('[NG HMR] dispose failed, falling back to full reload', e);
location.reload();
} Prevention
- Keep optimization.scripts disabled in serve/development configurations where HMR is used.
- Serve with --configuration development; reserve optimized builds for ng build.
- Add an angular.json lint rule or review step forbidding "optimization": true under serve options.
- If HMR state preservation is not needed, ignore this warning — it is non-fatal; the app still rebuilds (full reload).
When it happens
Trigger: mod.hot.dispose callback runs after an HMR update while the global identifier 'ng' is undefined — caused by running ng serve / the dev server with optimization.scripts enabled (e.g. "optimization": true in the serve configuration or NG_BUILD optimization env).
Common situations: 1) Serving with --configuration production (which enables optimization) while expecting HMR. 2) Custom serve configuration that sets "optimization": { "scripts": true }. 3) Copying build options into serve options. 4) HMR proxy setups where optimized vendor chunks hide the ng global.
Related errors
- The "dev-server" builder requires a target to be specified.
- The "@angular-devkit/build-angular:dev-server" builder is de
- The "publicHost" option will not be used because it is not s
- Prebundling has been configured but will not be used because
- Warning: This is a simple server for use in testing or debu
AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30).
Data as JSON: /api/errors/c95cc093ebe0f8b3.
Report an issue: GitHub.