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
- Keep `multiple` static per component instance (bind to a value that does not change)
- Destroy and recreate the mat-select (e.g. wrap with `*ngIf` keyed or `@if`) when mode must change
- 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
- Treat [multiple] as a static input per instance
- Derive mode once in ngOnInit from route/config data
- Recreate the select (ngIf/keyed block) when mode must change
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
- `compareWith` must be a function.
- Unsupported MatButton appearance "${appearance}"
- Value must be an array in multiple-selection mode.
- Maps event target that uses native events must have `addEven
- Unable to retrieve options for autocomplete. Autocomplete pa
AI-assisted analysis of angular/components@0411926e7d (2026-08-31).
Data as JSON: /api/errors/5b0bc317a788e543.
Report an issue: GitHub.