angular/angular-cli · info
[NG HMR] Cannot restore selected options.
Error message
[NG HMR] Cannot restore selected options.
What it means
A console.warn from the Angular CLI HMR helper meaning selected <option> states could not be restored after a hot reload. Like inputs, options are restored only when the count of new <option> elements equals the count captured before the update; otherwise the warning fires and select selections are lost.
Source
Thrown at packages/angular_devkit/build_angular/src/tools/webpack/plugins/hmr/hmr-accept.ts:240
dispatchEvents(newElement);
}
} else if (oldInputs.length) {
console.warn('[NG HMR] Cannot restore input/textarea values.');
}
// Restore option
const newOptions = document.querySelectorAll('option');
if (newOptions.length && newOptions.length === oldOptions.length) {
console.log('[NG HMR] Restoring selected options.');
for (let index = 0; index < newOptions.length; index++) {
const newElement = newOptions[index];
newElement.selected = oldOptions[index].selected;
dispatchEvents(newElement);
}
} else if (oldOptions.length) {
console.warn('[NG HMR] Cannot restore selected options.');
}
}
View on GitHub (pinned to bb72145f9a)
Solutions
- Re-select the value after HMR (form controls bound with reactive forms or ngModel usually restore the selection automatically once the model rebinds).
- Keep option lists stable across the edit, or drive selection from component state so it re-applies on the new DOM.
- Persist selection state (service/localStorage) and reapply after the update if options are dynamic.
- Disable HMR (--no-hmr) on pages where select state loss matters.
Example fix
// before (template-driven options, selection lost)
<option *ngFor="let o of opts">{{o}}</option>
// after (reactive binding restores value)
<select [formControl]="sel"><option *ngFor="let o of opts" [value]="o">{{o}}</option></select> Defensive patterns
Strategy: fallback
Validate before calling
const oldCount = document.querySelectorAll('option').length;
// after HMR update:
if (document.querySelectorAll('option').length !== oldCount) {
console.info('Option count changed; selections will not be restored by HMR.');
} Type guard
function canRestoreOptions(oldLen: number, newLen: number): boolean {
return oldLen > 0 && oldLen === newLen;
} Prevention
- Bind selects with reactive forms or ngModel so selection follows state.
- Keep dynamic option lists deterministic across HMR updates.
- Reapply select values from component state after updates.
- Prefer full reloads when editing code that renders options.
When it happens
Trigger: During restoreFormValues: oldOptions.length > 0 but newOptions.length !== oldOptions.length — the update changed the number of <option> elements in any select on the page (options added/removed), or new options were not yet rendered when restore ran.
Common situations: HMR update touches a component with a select whose options are generated dynamically (*ngFor over data that changed); options conditionally rendered; page contains multiple selects with option counts that differ after the update; async-loaded option lists not populated yet at restore time.
Related errors
- [NG HMR] Unknown input type ${oldElement.type}.
- [NG HMR] Cannot restore input/textarea values.
- [NG HMR] Cannot find the application root component.
- [NG HMR] Cannot get 'ApplicationRef'.
- [NG HMR] Cannot get 'PlatformRef'.
AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30).
Data as JSON: /api/errors/5272f004667f578a.
Report an issue: GitHub.