angular/components · error

mat-grid-list: tile with colspan ${tileCols} is wider than g

Error message

mat-grid-list: tile with colspan ${tileCols} is wider than grid with cols="${this.tracker.length}".

What it means

TileCoordinator._findMatchingGap validates that a tile's colspan fits within the grid's column count before searching for a free gap. A tile wider than the total number of columns can never be placed, so the coordinator throws immediately.

Source

Thrown at src/material/grid-list/tile-coordinator.ts:98

  /** Calculates the row and col position of a tile. */
  private _trackTile(tile: Tile): TilePosition {
    // Find a gap large enough for this tile.
    const gapStartIndex = this._findMatchingGap(tile.colspan);

    // Place tile in the resulting gap.
    this._markTilePosition(gapStartIndex, tile);

    // The next time we look for a gap, the search will start at columnIndex, which should be
    // immediately after the tile that has just been placed.
    this.columnIndex = gapStartIndex + tile.colspan;

    return new TilePosition(this.rowIndex, gapStartIndex);
  }

  /** Finds the next available space large enough to fit the tile. */
  private _findMatchingGap(tileCols: number): number {
    if (tileCols > this.tracker.length) {
      throw Error(
        `mat-grid-list: tile with colspan ${tileCols} is wider than grid with cols="${this.tracker.length}".`,
      );
    }

    // Start index is inclusive, end index is exclusive.
    let gapStartIndex = -1;
    let gapEndIndex = -1;

    // Look for a gap large enough to fit the given tile. Empty spaces are marked with a zero.
    do {
      // If we've reached the end of the row, go to the next row.
      if (this.columnIndex + tileCols > this.tracker.length) {
        this._nextRow();
        gapStartIndex = this.tracker.indexOf(0, this.columnIndex);
        gapEndIndex = this._findGapEndIndex(gapStartIndex);
        continue;
      }

View on GitHub (pinned to 0411926e7d)

Solutions

  1. Ensure every tile's colspan is <= the grid's cols value.
  2. Clamp dynamic colspans: [colspan]="span > cols ? cols : span".
  3. Increase cols on mat-grid-list if the wide tile is intentional.
  4. Audit templates after changing cols so no tile keeps a stale, larger colspan.

Example fix

// before
<mat-grid-list cols="3">
  <mat-grid-tile [colspan]="4"></mat-grid-tile>
</mat-grid-list>
// after
<mat-grid-list cols="4">
  <mat-grid-tile [colspan]="4"></mat-grid-tile>
</mat-grid-list>
Defensive patterns

Strategy: validation

Validate before calling

// before binding tile colspans
function clampColspan(span: number, cols: number): number {
  return Math.max(1, Math.min(span, cols));
}
// template: <mat-grid-tile [colspan]="clampColspan(span, cols)">

Type guard

function fitsGrid(span: number, cols: number): boolean {
  return Number.isInteger(span) && span >= 1 && span <= cols;
}

Prevention

When it happens

Trigger: Setting [colspan] on a mat-grid-tile greater than the grid's cols value, e.g. <mat-grid-tile [colspan]="4"> inside <mat-grid-list cols="3">, or a dynamic colspan variable that exceeds cols.

Common situations: Changing cols to a smaller number while tiles keep large static colspan values; binding colspan to computed data that can exceed cols; copy-pasting tiles between grids with different column counts.

Related errors


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