angular/components · error

Cannot change `multiple` mode of select after initialization

Error message

Cannot change `multiple` mode of select after initialization.

What it means

MatSelect's `multiple` input throws if changed after the select has initialized (once `_selectionModel` exists). Switching between single and multi mode after init would corrupt the selection model, so Angular Material forbids it in dev mode.

Source

Thrown at src/material/select/select.ts:447

  /** Whether the component is required. */
  @Input({transform: booleanAttribute})
  get required(): boolean {
    return this._required ?? this.ngControl?.control?.hasValidator(Validators.required) ?? false;
  }
  set required(value: boolean) {
    this._required = value;
    this.stateChanges.next();
  }
  private _required: boolean | undefined;

  /** Whether the user should be allowed to select multiple options. */
  @Input({transform: booleanAttribute})
  get multiple(): boolean {
    return this._multiple;
  }
  set multiple(value: boolean) {
    if (this._selectionModel && (typeof ngDevMode === 'undefined' || ngDevMode)) {
      throw getMatSelectDynamicMultipleError();
    }

    this._multiple = value;
  }
  private _multiple: boolean = false;

  /** Whether to center the active option over the trigger. */
  @Input({transform: booleanAttribute})
  disableOptionCentering = this._defaultOptions?.disableOptionCentering ?? false;

  /**
   * Function to compare the option values with the selected values. The first argument
   * is a value from an option. The second is a value from the selection. A boolean
   * should be returned.
   */
  @Input()
  get compareWith() {
    return this._compareWith;

View on GitHub (pinned to 0411926e7d)

Solutions

  1. Keep `multiple` static per component instance (bind to a value that does not change)
  2. Destroy and recreate the mat-select (e.g. wrap with `*ngIf` keyed or `@if`) when mode must change
  3. Initialize the mode before the select is rendered, e.g. compute it in ngOnInit from route/config

Example fix

// before
<mat-select [multiple]="dynamicMode">...</mat-select>
// after
@if (dynamicMode) {
  <mat-select multiple>...</mat-select>
} @else {
  <mat-select>...</mat-select>
}
Defensive patterns

Strategy: validation

Validate before calling

// Guard before binding: keep the multiple flag fixed for the component lifetime
if (select._selectionModel && multipleChanged) {
  throw new Error('Do not change [multiple] after mat-select initialization');
}

Try / catch

try {
  component.isMulti = !component.isMulti;
  fixture.detectChanges();
} catch (e) {
  if (String(e?.message).includes('multiple` mode')) {
    fail('Recreate the mat-select instead of toggling [multiple]');
  }
  throw e;
}

Prevention

When it happens

Trigger: Binding `[multiple]` to a value that changes at runtime (e.g. `[multiple]="isMulti"` toggled by user action or route data), or setting the property imperatively after the view initializes.

Common situations: Dynamic forms that toggle select mode based on config; Angular restructuring where a new component instance was expected but the same one is reused; setting the input in `ngAfterViewInit` or later.

Related errors


AI-assisted analysis of angular/components@0411926e7d (2026-08-31). Data as JSON: /api/errors/5b0bc317a788e543. Report an issue: GitHub.