angular/components · error · Error

CdkSelection: index required when trackBy is used

Error message

CdkSelection: index required when trackBy is used

What it means

CdkSelection.toggleSelection throws in dev mode when a trackByFn is configured on the CdkSelection but the caller omits the index argument. With track-by, items are identified by trackByFn(index, value), so toggling identity cannot be computed without the index.

Source

Thrown at src/cdk-experimental/selection/selection.ts:143

  ngAfterContentChecked() {
    if (this._dataSource && !this._renderChangeSubscription) {
      this._observeRenderChanges();
    }
  }

  ngOnDestroy() {
    this._destroyed.next();
    this._destroyed.complete();

    if (isDataSource(this._dataSource)) {
      this._dataSource.disconnect(this);
    }
  }

  /** Toggles selection for a given value. `index` is required if `trackBy` is used. */
  toggleSelection(value: T, index?: number) {
    if (!!this.trackByFn && index == null && (typeof ngDevMode === 'undefined' || ngDevMode)) {
      throw Error('CdkSelection: index required when trackBy is used');
    }

    if (this.isSelected(value, index)) {
      this._selection.deselect({value, index});
    } else {
      this._selection.select({value, index});
    }
  }

  /**
   * Toggles select-all. If no value is selected, select all values. If all values or some of the
   * values are selected, de-select all values.
   */
  toggleSelectAll() {
    if (!this._multiple && (typeof ngDevMode === 'undefined' || ngDevMode)) {
      throw Error('CdkSelection: multiple selection not enabled');
    }

View on GitHub (pinned to 0411926e7d)

Solutions

  1. Pass the row index: toggleSelection(value, i), e.g., inside *cdkRow or *cdkItem where the index is provided.
  2. Remove the trackBy input if value-only identity is acceptable.
  3. Make index required in wrapper helpers so the compiler enforces it.

Example fix

// before
selection.toggleSelection(row.value);

// after
selection.toggleSelection(row.value, row.index);
Defensive patterns

Strategy: validation

Validate before calling

function canToggle(trackByFn: unknown, index?: number): boolean {
  return !trackByFn || index != null;
}
if (!canToggle(selection.trackByFn, idx)) throw new Error('toggleSelection requires index when trackBy is set');
selection.toggleSelection(value, idx);

Type guard

function hasToggleIndex(value: unknown, index: number | undefined): index is number {
  return index != null;
}

Try / catch

try {
  selection.toggleSelection(value, index);
} catch (e) {
  if ((e as Error).message.includes('index required')) {
    console.warn('Supply the row index when using trackBy');
  } else throw e;
}

Prevention

When it happens

Trigger: Calling selection.toggleSelection(value) with no second argument on a CdkSelection that has [trackBy] set. Calling without trackBy is fine.

Common situations: Click handlers bound only to the row value; template method calls like toggleSelection(row) written before trackBy was added; helper functions that drop optional parameters.

Related errors


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