angular/components · error · Error

Value must be an array in multiple-selection mode.

Error message

Value must be an array in multiple-selection mode.

What it means

MatButtonToggleGroup with multiple=true expects its value binding to be an array of selected toggle values. When _setSelectionByValue runs (via the group's value setter) and multiple is enabled, a non-array truthy value cannot be mapped onto individual toggles, so the library throws in dev mode.

Source

Thrown at src/material/button-toggle/button-toggle.ts:481

      }
    }

    return null;
  }

  /** Updates the selection state of the toggles in the group based on a value. */
  private _setSelectionByValue(value: any | any[]) {
    this._rawValue = value;

    if (!this._buttonToggles) {
      return;
    }

    const toggles = this._buttonToggles.toArray();

    if (this.multiple && value) {
      if (!Array.isArray(value) && (typeof ngDevMode === 'undefined' || ngDevMode)) {
        throw Error('Value must be an array in multiple-selection mode.');
      }

      this._clearSelection();
      value.forEach((currentValue: any) => this._selectValue(currentValue, toggles));
    } else {
      this._clearSelection();
      this._selectValue(value, toggles);
    }

    // In single selection mode we need at least one enabled toggle to always be focusable.
    if (!this.multiple && toggles.every(toggle => toggle.tabIndex === -1)) {
      for (const toggle of toggles) {
        if (!toggle.disabled) {
          toggle.tabIndex = 0;
          break;
        }
      }
    }

View on GitHub (pinned to 0411926e7d)

Solutions

  1. Provide an array as the value: [value]="['a','b']" or FormControl with an array value.
  2. Type the form control as FormControl<string[]> when using multiple.
  3. If single selection is intended, remove the multiple attribute.
  4. Guard initial data so async-loaded values default to [] instead of a scalar or undefined-shaped scalar.

Example fix

// before
ctrl = new FormControl('java');
<mat-button-toggle-group [formControl]="ctrl" multiple>
// after
ctrl = new FormControl(['java']);
<mat-button-toggle-group [formControl]="ctrl" multiple>
Defensive patterns

Strategy: type-guard

Validate before calling

const value = group.value;
if (group.multiple && !Array.isArray(value)) {
  throw new TypeError('multiple mat-button-toggle-group requires array value');
}

Type guard

function isArrayValue(v: unknown): v is any[] {
  return Array.isArray(v);
}

Try / catch

try {
  group.value = selected as string[];
} catch (e) {
  if (e instanceof Error && e.message.includes('must be an array in multiple-selection mode')) {
    group.value = Array.isArray(selected) ? selected : [selected];
  } else { throw e; }
}

Prevention

When it happens

Trigger: Binding [value] on a <mat-button-toggle-group multiple> to a non-array value (string, number, object), or programmatically setting group.value = 'foo' while multiple is true.

Common situations: Form controls typed as single-value (FormControl<string>) attached to a multiple group; switching a group from single to multiple selection without changing the value shape; server data returning a single value instead of an array.

Related errors


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