angular/components · error

Could not find a matching row definition for the provided ro

Error message

Could not find a matching row definition for the provided row data: ${JSON.stringify(data)}

What it means

During rendering the table collects row definitions whose `when` predicate matches each data item (or the default def). If no row def matched for a particular data item, it throws with the JSON of that data. This happens when only conditional row defs exist and an item satisfies none of them.

Source

Thrown at src/cdk/table/table.ts:1340

   */
  _getRowDefs(data: T, dataIndex: number): CdkRowDef<T>[] {
    if (this._rowDefs.length === 1) {
      return [this._rowDefs[0]];
    }

    let rowDefs: CdkRowDef<T>[] = [];
    if (this.multiTemplateDataRows) {
      rowDefs = this._rowDefs.filter(def => !def.when || def.when(dataIndex, data));
    } else {
      let rowDef =
        this._rowDefs.find(def => def.when && def.when(dataIndex, data)) || this._defaultRowDef;
      if (rowDef) {
        rowDefs.push(rowDef);
      }
    }

    if (!rowDefs.length && (typeof ngDevMode === 'undefined' || ngDevMode)) {
      throw getTableMissingMatchingRowDefError(data);
    }

    return rowDefs;
  }

  private _getEmbeddedViewArgs(
    renderRow: RenderRow<T>,
    index: number,
  ): _ViewRepeaterItemInsertArgs<RowContext<T>> {
    const rowDef = renderRow.rowDef;
    const context: RowContext<T> = {$implicit: renderRow.data};
    return {
      templateRef: rowDef.template,
      context,
      index,
    };
  }

View on GitHub (pinned to 0411926e7d)

Solutions

  1. Add a default row def without `when` as a catch-all: <tr mat-row *matRowDef="let row; columns: cols"></tr>
  2. Extend one predicate to cover the unmatched data shape
  3. Enable [multiTemplateDataRows]="true" if items should match multiple defs and fix predicates accordingly
  4. Log/filter data items that fail all predicates during development

Example fix

// before — only conditional defs, item {type:'other'} matches none
<tr mat-row *matRowDef="let row; columns: cols; when: isUser"></tr>
// after — add fallback default def
<tr mat-row *matRowDef="let row; columns: cols; when: isUser"></tr>
<tr mat-row *matRowDef="let row; columns: genericCols"></tr>
Defensive patterns

Strategy: validation

Validate before calling

const predicates = rowDefs.map(d => d.when).filter(Boolean);
const unmatched = data.filter(item =>
  !rowDefs.some(d => d.when ? d.when(item) : true));
if (unmatched.length) throw new Error(`No row def matches: ${JSON.stringify(unmatched[0])}`);

Type guard

function allItemsMatchARowDef<T>(data: T[], rowDefs: {when?: (d: T) => boolean}[]): data is T[] {
  return data.every(item => rowDefs.some(d => d.when ? d.when(item) : true));
}

Try / catch

try {
  this.cdr.detectChanges();
} catch (e) {
  if (/matching row definition/.test(e.message)) {
    console.error('Add a default (no-when) row def or broaden a when predicate.');
  }
}

Prevention

When it happens

Trigger: _getAllRenderRows / rowDefs gathering: for a data item, every *matRowDef has a when predicate that returned false and there is no default (no-when) row def, leaving rowDefs.length === 0.

Common situations: A row type in the data (e.g. a discriminated union member like 'unknown') not covered by any when predicate; predicates narrowed by an earlier filter change; data source updated at runtime to include new shapes the templates don't handle.

Related errors


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