angular/components · error
mat-grid-list: invalid ratio given for row-height: "${value}
Error message
mat-grid-list: invalid ratio given for row-height: "${value}" What it means
When rowHeight is given as a ratio string (e.g. '1:1' or '4:3'), RatioRowStyler._parseRatio splits on ':' and requires exactly two parts. Any string with a different number of ':'-separated segments throws this error.
Source
Thrown at src/material/grid-list/tile-styler.ts:260
'paddingBottom',
calc(`${this.getTileSpan(this.baseTileHeight)} + ${this.getGutterSpan()}`),
];
}
reset(list: TileStyleTarget) {
list._setListStyle(['paddingBottom', null]);
list._tiles.forEach(tile => {
tile._setStyle('marginTop', null);
tile._setStyle('paddingTop', null);
});
}
private _parseRatio(value: string): void {
const ratioParts = value.split(':');
if (ratioParts.length !== 2 && (typeof ngDevMode === 'undefined' || ngDevMode)) {
throw Error(`mat-grid-list: invalid ratio given for row-height: "${value}"`);
}
this.rowHeightRatio = parseFloat(ratioParts[0]) / parseFloat(ratioParts[1]);
}
}
/**
* This type of styler is instantiated when the user selects a "fit" row height mode.
* In other words, the row height will reflect the total height of the container divided
* by the number of rows. Example `<mat-grid-list cols="3" rowHeight="fit">`
*
* @docs-private
*/
export class FitTileStyler extends TileStyler {
setRowStyles(tile: MatGridTile, rowIndex: number): void {
// Percent of the available vertical space that one row takes up.
let percentHeightPerTile = 100 / this._rowspan;
View on GitHub (pinned to 0411926e7d)
Solutions
- Provide exactly two segments separated by one colon: rowHeight="1:1" or "4:3".
- If a fixed height was intended, pass a number or CSS unit instead (rowHeight="100px").
- Validate dynamic ratio strings before binding: /^\d+(\.\d+)?:\d+(\.\d+)?$/.test(v).
- Check binding interpolation for stray colons from template expressions.
Example fix
// before <mat-grid-list cols="3" rowHeight="1"> // after <mat-grid-list cols="3" rowHeight="1:1"></mat-grid-list>
Defensive patterns
Strategy: validation
Validate before calling
function isRatioRowHeight(v: string): boolean {
return v.split(':').length === 2 && v.split(':').every(p => p.trim() !== '' && !isNaN(Number(p)));
} Type guard
function isRatioString(v: unknown): v is `${number}:${number}` {
return typeof v === 'string' && /^\d+(\.\d+)?:\d+(\.\d+)?$/.test(v);
} Prevention
- Ratio rowHeight must contain exactly one colon with two numeric parts.
- If no colon is intended, pass a number or px string instead.
- Validate dynamically composed ratio strings before binding.
When it happens
Trigger: Passing rowHeight="1" (no colon, intended as ratio), rowHeight="1:1:1" (extra segment), or rowHeight="" with the ratio styler selected — anything whose split(':') length !== 2.
Common situations: Confusing the fixed-height and ratio syntax (forgetting the colon); dynamically building the ratio string and appending an extra part; empty bindings that should have been numbers.
Related errors
- Invalid value "${this.fixedRowHeight}" set as rowHeight.
- mat-grid-list: must pass in number of columns. Example: <mat
- Could not find tile at given position.
- mat-grid-list: tile with colspan ${tileCols} is wider than g
- xPosition value must be either 'before' or after'. Exa
AI-assisted analysis of angular/components@0411926e7d (2026-08-31).
Data as JSON: /api/errors/3692b0ec8a112b97.
Report an issue: GitHub.