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
- Add a default row def without `when` as a catch-all: <tr mat-row *matRowDef="let row; columns: cols"></tr>
- Extend one predicate to cover the unmatched data shape
- Enable [multiTemplateDataRows]="true" if items should match multiple defs and fix predicates accordingly
- 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
- Always include one default row def as a catch-all
- Cover every member of a discriminated union with a when predicate
- Re-validate predicates when data shapes change
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
- There can only be one default row without a when predicate f
- Conditional row definitions via the `when` input are not sup
- Missing definitions for header, footer, and row; cannot dete
- Duplicate column definition name provided: "${columnDef.name
- Provided data source did not match an array, Observable, or
AI-assisted analysis of angular/components@0411926e7d (2026-08-31).
Data as JSON: /api/errors/b1f8c3278fd122d5.
Report an issue: GitHub.