angular/components · error

Text column could not find a parent table for registration.

Error message

Text column could not find a parent table for registration.

What it means

MatTextColumn must be declared inside a mat-table because ngOnInit injects the parent table via MAT_TABLE and registers its column def with it. When no parent table is found (injection or @ContentChild lookup failed) and dev mode is on, the component throws.

Source

Thrown at src/cdk/table/text-column.ts:138

    if (this.headerText === undefined) {
      this.headerText = this._createDefaultHeaderText();
    }

    if (!this.dataAccessor) {
      this.dataAccessor =
        this._options.defaultDataAccessor || ((data: T, name: string) => (data as any)[name]);
    }

    if (this._table) {
      // Provide the cell and headerCell directly to the table with the static `ViewChild` query,
      // since the columnDef will not pick up its content by the time the table finishes checking
      // its content and initializing the rows.
      this.columnDef.cell = this.cell;
      this.columnDef.headerCell = this.headerCell;
      this._table.addColumnDef(this.columnDef);
    } else if (typeof ngDevMode === 'undefined' || ngDevMode) {
      throw getTableTextColumnMissingParentTableError();
    }
  }

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

  /**
   * Creates a default header text. Use the options' header text transformation function if one
   * has been provided. Otherwise simply capitalize the column name.
   */
  _createDefaultHeaderText() {
    const name = this.name;

    if (!name && (typeof ngDevMode === 'undefined' || ngDevMode)) {
      throw getTableTextColumnMissingNameError();

View on GitHub (pinned to 0411926e7d)

Solutions

  1. Move the <mat-text-column> element directly inside <table mat-table>...</table>
  2. Ensure MatTableModule (or MatModule) is imported so the MAT_TABLE provider exists
  3. If wrapping in a custom component, re-provide/inject MAT_TABLE and pass it down via the `table` input
  4. Check that the table is a real mat-table (not plain table without the directive)

Example fix

// before
<div class="wrapper"><mat-text-column name="score"></mat-text-column></div>
<table mat-table [dataSource]=data> ... </table>
// after
<table mat-table [dataSource]=data>
  <mat-text-column name="score"></mat-text-column>
  ...
</table>
Defensive patterns

Strategy: validation

Validate before calling

const table = hostEl.closest('table[mat-table]');
if (!table) throw new Error('mat-text-column must be placed inside a mat-table');

Type guard

function isInsideMatTable(el: Element): boolean {
  return !!el.closest('table[mat-table]');
}

Try / catch

try {
  this.cdr.detectChanges();
} catch (e) {
  if (/could not find a parent table/.test(e.message)) {
    console.error('Move <mat-text-column> inside <table mat-table>.');
  }
}

Prevention

When it happens

Trigger: TextColumn.ngOnInit: this._table is null/undefined when it tries this._table.addColumnDef(this.columnDef) — e.g. <mat-text-column> placed outside <mat-table>, or inside a component that isn't projecting it into the table.

Common situations: Placing mat-text-column in a sibling container rather than directly inside mat-table; using MatTextColumn without importing MatTableModule so the table provider is missing; wrapping the column in a custom component without forwarding the table injection.

Related errors


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