angular/components · error

Could not find column with id "${columnId}".

Error message

Could not find column with id "${columnId}".

What it means

When extracting cell templates for a row definition, the table resolves each column id in rowDef.columns against registered column defs; an id with no registered CdkColumnDef throws this error. Same family as error 134 but raised while building the actual cell templates rather than sticky styles.

Source

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

      if (this.multiTemplateDataRows) {
        context.dataIndex = this._renderRows[renderIndex].dataIndex;
        context.renderIndex = renderIndex;
      } else {
        context.index = this._renderRows[renderIndex].dataIndex;
      }
    }
  }

  /** Gets the column definitions for the provided row def. */
  private _getCellTemplates(rowDef: BaseRowDef): TemplateRef<any>[] {
    if (!rowDef || !rowDef.columns) {
      return [];
    }
    return Array.from(rowDef.columns, columnId => {
      const column = this._columnDefsByName.get(columnId);

      if (!column) {
        throw getTableUnknownColumnError(columnId);
      }

      return rowDef.extractCellTemplate(column);
    });
  }

  /**
   * Forces a re-render of the data rows. Should be called in cases where there has been an input
   * change that affects the evaluation of which rows should be rendered, e.g. toggling
   * `multiTemplateDataRows` or adding/removing row definitions.
   */
  private _forceRenderDataRows() {
    this._dataDiffer.diff([]);
    this._rowOutlet.viewContainer.clear();
    this.renderRows();
  }

  /**

View on GitHub (pinned to 0411926e7d)

Solutions

  1. Ensure every id in the row def's columns is declared as <ng-container matColumnDef="id"> within this table
  2. Fix typos/case mismatches in the columns property of *matRowDef/*matHeaderRowDef
  3. Remove or update stale column ids in the row def
  4. Keep each row def's columns scoped to its own table's column defs

Example fix

// before
<tr mat-row *matRowDef="let row; columns: ['name', 'qtyy']"></tr> <!-- qtyy undeclared -->
// after
<tr mat-row *matRowDef="let row; columns: ['name', 'qty']"></tr>
Defensive patterns

Strategy: validation

Validate before calling

const declared = new Set(Array.from(el.querySelectorAll('[matColumnDef]')).map(c => c.getAttribute('matColumnDef')));
rowDefColumns.forEach(id => { if (!declared.has(id)) throw new Error(`Row def references undeclared column: ${id}`); });

Type guard

function rowColumnsDeclared(cols: string[], declared: Set<string>): cols is string[] {
  return cols.every(c => declared.has(c));
}

Try / catch

try {
  this.cdr.detectChanges();
} catch (e) {
  if (/Could not find column with id/.test(e.message)) {
    console.error('Row def columns must all have matColumnDef declarations in this table.');
  }
}

Prevention

When it happens

Trigger: _getCellTemplates / renderRow: Array.from(rowDef.columns, columnId => this._columnDefsByName.get(columnId)) returns undefined for some columnId — the row def's columns input names a column that doesn't exist in the table.

Common situations: matRowDef columns list containing ids not declared via matColumnDef (typo, removed column, wrong table); reusing a rowDef across two tables; dynamically computed column lists with stale entries.

Related errors


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