angular/components · error

Duplicate column definition name provided: "${columnDef.name

Error message

Duplicate column definition name provided: "${columnDef.name}".

What it means

Two or more CdkColumnDef instances registered with the table share the same `name`. The table keeps a map of column name -> definition (_columnDefsByName) and refuses ambiguous duplicates because it could not resolve which cell template to use. Thrown during content init / column def registration in dev mode.

Source

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

        return {data, rowDef, dataIndex};
      }
    });
  }

  /** Update the map containing the content's column definitions. */
  private _cacheColumnDefs() {
    this._columnDefsByName.clear();

    const columnDefs = mergeArrayAndSet(
      this._getOwnDefs(this._contentColumnDefs),
      this._customColumnDefs,
    );
    columnDefs.forEach(columnDef => {
      if (
        this._columnDefsByName.has(columnDef.name) &&
        (typeof ngDevMode === 'undefined' || ngDevMode)
      ) {
        throw getTableDuplicateColumnNameError(columnDef.name);
      }
      this._columnDefsByName.set(columnDef.name, columnDef);
    });
  }

  /** Update the list of all available row definitions that can be used. */
  private _cacheRowDefs() {
    this._headerRowDefs = mergeArrayAndSet(
      this._getOwnDefs(this._contentHeaderRowDefs),
      this._customHeaderRowDefs,
    );
    this._footerRowDefs = mergeArrayAndSet(
      this._getOwnDefs(this._contentFooterRowDefs),
      this._customFooterRowDefs,
    );
    this._rowDefs = mergeArrayAndSet(this._getOwnDefs(this._contentRowDefs), this._customRowDefs);

    // After all row definitions are determined, find the row definition to be considered default.

View on GitHub (pinned to 0411926e7d)

Solutions

  1. Rename one of the duplicate matColumnDef/cdkColumnDef values so each name in a table is unique
  2. Search the table's template for repeated matColumnDef="x" values (e.g. duplicate of 'name')
  3. If columns come from a *ngFor over a config array, ensure the config has unique ids
  4. Make sure the same columnDef template isn't projected into the table twice

Example fix

// before
<ng-container matColumnDef="name">...</ng-container>
<ng-container matColumnDef="name">...</ng-container>
// after
<ng-container matColumnDef="name">...</ng-container>
<ng-container matColumnDef="description">...</ng-container>
Defensive patterns

Strategy: validation

Validate before calling

const ids = Array.from(el.querySelectorAll('[matColumnDef]')).map(c => c.getAttribute('matColumnDef'));
const dupes = ids.filter((id, i) => ids.indexOf(id) !== i);
if (dupes.length) throw new Error(`Duplicate matColumnDef ids: ${dupes.join(',')}`);

Type guard

function hasUniqueColumnIds(ids: string[]): ids is string[] {
  return new Set(ids).size === ids.length;
}

Try / catch

try {
  this.cdr.detectChanges();
} catch (e) {
  if (/Duplicate column definition name/.test(e.message)) {
    console.error('Rename one of the duplicated matColumnDef ids:', e.message);
  }
}

Prevention

When it happens

Trigger: _syncColumnDefs → columnDefs.forEach when this._columnDefsByName.has(columnDef.name) is true while registering column defs, e.g. two <ng-container matColumnDef="name"> blocks in the same table.

Common situations: Copy-pasting a column and forgetting to change matColumnDef value; two tables nested or sharing template content causing double registration; refactoring where a column id was duplicated by merge conflict.

Related errors


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