angular/angular-cli · info

[NG HMR] Cannot restore input/textarea values.

Error message

[NG HMR] Cannot restore input/textarea values.

What it means

A console.warn from the Angular CLI HMR helper meaning input/textarea values could not be restored after a hot reload. Restoration only happens when the number of new visible inputs/textareas exactly equals the number captured before the update; if they differ (or newInputs is empty) while oldInputs existed, the warning fires and previously typed values are lost.

Source

Thrown at packages/angular_devkit/build_angular/src/tools/webpack/plugins/hmr/hmr-accept.ts:226

        case 'textarea':
        case 'time':
        case 'url':
        case 'week':
          newElement.value = oldElement.value;
          break;
        case 'file':
          // Ignored due: Uncaught DOMException: Failed to set the 'value' property on 'HTMLInputElement':
          // This input element accepts a filename, which may only be programmatically set to the empty string.
          break;
        default:
          console.warn('[NG HMR] Unknown input type ' + oldElement.type + '.');
          continue;
      }

      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

  1. Expect this when the HMR update changes form structure; a full browser reload restores a clean state — just re-enter values or persist them.
  2. Keep form structure stable while iterating (persist draft values in a service, localStorage, or NgRx so they survive HMR).
  3. If inputs are conditionally rendered, ensure the same conditions hold before and after the update so counts match.
  4. Disable HMR (--no-hmr) for form-heavy pages where state loss is disruptive.

Example fix

// before (values lost on every HMR)
save() { this.api.save(this.form.value); }
// after (draft survives HMR/reload)
this.form.valueChanges.subscribe(v => localStorage.setItem('draft', JSON.stringify(v)));
Defensive patterns

Strategy: fallback

Validate before calling

const before = document.querySelectorAll('input:not([type="hidden"]), textarea').length;
// after the HMR update:
const after = document.querySelectorAll('input:not([type="hidden"]), textarea').length;
if (before !== after) console.info('Form structure changed; values will not be restored by HMR.');

Type guard

function canRestoreFormValues(oldLen: number, newLen: number): boolean {
  return oldLen > 0 && oldLen === newLen;
}

Prevention

When it happens

Trigger: During restoreFormValues: oldInputs.length > 0 but newInputs.length !== oldInputs.length — the HMR update added or removed input/textarea elements, moved them out of document scope, or the new app rendered different markup.

Common situations: Editing a template/component in a way that changes the number or kind of form fields (adding a field, conditionally rendering inputs with *ngIf); HMR updating a lazy-loaded chunk that renders a different form; components that rebuild the DOM asynchronously so inputs are not present when restore runs.

Related errors


AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30). Data as JSON: /api/errors/36bffb4d5a035ffc. Report an issue: GitHub.