angular/components · error

There can only be one default row without a when predicate f

Error message

There can only be one default row without a when predicate function. Or set `multiTemplateDataRows`.

What it means

More than one row definition lacks a `when` predicate (i.e. multiple 'default' row defs) while multiTemplateDataRows is false. The table cannot decide which default def to use for a data row. Thrown in _syncRowDefs during content init in dev mode.

Source

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

    );
    this._rowDefs = mergeArrayAndSet(this._getOwnDefs(this._contentRowDefs), this._customRowDefs);

    // After all row definitions are determined, find the row definition to be considered default.
    const defaultRowDefs = this._rowDefs.filter(def => !def.when);

    if (typeof ngDevMode === 'undefined' || ngDevMode) {
      // At the moment of writing, it's tricky to support `when` with virtual scrolling
      // because we reuse templates and they can change arbitrarily based on the `when`
      // condition. We may be able to support it in the future (see #32670).
      if (this._virtualScrollEnabled() && this._rowDefs.some(def => def.when)) {
        throw new Error(
          'Conditional row definitions via the `when` input are not ' +
            'supported when virtual scrolling is enabled, at the moment.',
        );
      }

      if (!this.multiTemplateDataRows && defaultRowDefs.length > 1) {
        throw getTableMultipleDefaultRowDefsError();
      }
    }
    this._defaultRowDef = defaultRowDefs[0];
  }

  /**
   * Check if the header, data, or footer rows have changed what columns they want to display or
   * whether the sticky states have changed for the header or footer. If there is a diff, then
   * re-render that section.
   */
  private _renderUpdatedColumns(): boolean {
    const columnsDiffReducer = (acc: boolean, def: BaseRowDef) => {
      // The differ should be run for every column, even if `acc` is already
      // true (see #29922)
      const diff = !!def.getColumnsDiff();
      return acc || diff;
    };

View on GitHub (pinned to 0411926e7d)

Solutions

  1. Add a `when` predicate to all but one row def, e.g. *matRowDef="let row; columns: cols; when: isSpecial"
  2. Set [multiTemplateDataRows]="true" on the table to allow multiple rows per data item
  3. Remove the redundant default row definition
  4. If using virtual scrolling, remove when-based row defs (unsupported there)

Example fix

// before
<tr mat-row *matRowDef="let row; columns: cols"></tr>
<tr mat-row *matRowDef="let row; columns: altCols"></tr>
// after
<tr mat-row *matRowDef="let row; columns: cols; when: isSpecial"></tr>
<tr mat-row *matRowDef="let row; columns: altCols"></tr>
Defensive patterns

Strategy: validation

Validate before calling

const defs = Array.from(el.querySelectorAll('tr[matRowDef]'));
const defaults = defs.filter(d => !d.getAttribute('matRowDef')?.includes('when'));
if (defaults.length > 1 && !table.multiTemplateDataRows) {
  throw new Error('Only one default (no-when) row def allowed, or set multiTemplateDataRows');
}

Type guard

function hasSingleDefaultRowDef(rowDefs: {when?: (d: any) => boolean}[], multi: boolean): boolean {
  return multi || rowDefs.filter(d => !d.when).length <= 1;
}

Try / catch

try {
  this.cdr.detectChanges();
} catch (e) {
  if (/only be one default row/.test(e.message)) {
    console.error('Add a when predicate to extra row defs or set [multiTemplateDataRows]=true');
  }
}

Prevention

When it happens

Trigger: Two or more <tr mat-row *matRowDef="let row; columns: cols;"> without when, and [multiTemplateDataRows] not set to true; note also that when-conditional defs are unsupported with virtual scrolling at this point.

Common situations: Adding a second row template for styling alternates but forgetting when: predicates; wanting multiple row types without enabling multiTemplateDataRows; combining CdkVirtualScrollViewport with when-based rows.

Related errors


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