angular/components · error · Error

CdkSelectionColumn: missing parent table

Error message

CdkSelectionColumn: missing parent table

What it means

CdkSelectionColumn registers its CdkColumnDef (cell/header cell definitions) with a parent CdkTable via addColumnDef. When the component is not rendered inside a CDK table, this._table is undefined and ngOnInit throws this dev-mode error instead of silently failing to register the column. Without a table the column has no rendering target.

Source

Thrown at src/cdk-experimental/selection/selection-column.ts:98

  private _name!: string;

  @ViewChild(CdkColumnDef, {static: true}) private readonly _columnDef!: CdkColumnDef;
  @ViewChild(CdkCellDef, {static: true}) private readonly _cell!: CdkCellDef;
  @ViewChild(CdkHeaderCellDef, {static: true}) private readonly _headerCell!: CdkHeaderCellDef;

  ngOnInit() {
    if (!this.selection && (typeof ngDevMode === 'undefined' || ngDevMode)) {
      throw Error('CdkSelectionColumn: missing CdkSelection in the parent');
    }

    this._syncColumnDefName();

    if (this._table) {
      this._columnDef.cell = this._cell;
      this._columnDef.headerCell = this._headerCell;
      this._table.addColumnDef(this._columnDef);
    } else if (typeof ngDevMode === 'undefined' || ngDevMode) {
      throw Error('CdkSelectionColumn: missing parent table');
    }
  }

  ngOnDestroy() {
    if (this._table) {
      this._table.removeColumnDef(this._columnDef);
    }
  }

  private _syncColumnDefName() {
    if (this._columnDef) {
      this._columnDef.name = this._name;
    }
  }
}

View on GitHub (pinned to 0411926e7d)

Solutions

  1. Render the selection column inside a <cdk-table> (or MatTable) so the table can be injected and the column registered.
  2. Verify the element is a direct part of the table's projected content (inside th/td rows of cdk-table), not a detached wrapper.
  3. Check that you imported/declared both the table and selection-column components from the experimental selection/tables modules.

Example fix

// before
<cdk-selection><th cdk-selection-column/></cdk-selection>
// after
<cdk-selection [multiple]="true">
  <cdk-table [dataSource]="data">
    <ng-container cdkColumnDef="select">
      <th cdk-header-cell cdk-selection-column *cdkHeaderCellDef></th>
    </ng-container>
  </cdk-table>
</cdk-selection>
Defensive patterns

Strategy: validation

Validate before calling

if (!document.querySelector('cdk-table, mat-table')) {
  // selection column has no table to register with
}

Try / catch

ngAfterContentInit() {
  if (!this._table) {
    throw new Error('cdk-selection-column must be placed inside a cdk-table');
  }
}

Prevention

When it happens

Trigger: Placing <cdk-selection-column> (or its th/td markup) outside any <cdk-table>/mat-table so the injected table reference is undefined when ngOnInit runs.

Common situations: Using the selection column markup in a plain HTML table or a custom non-CDK table; accidentally nesting it in a wrapper that breaks content projection into the table; typos in selectors so the table child query misses.

Related errors


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