{"record":{"id":"3692b0ec8a112b97","repo":"angular/components","slug":"mat-grid-list-invalid-ratio-given-for-row-height","errorCode":null,"errorMessage":"mat-grid-list: invalid ratio given for row-height: \"${value}\"","messagePattern":"mat-grid-list: invalid ratio given for row-height: \"(.+?)\"","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/material/grid-list/tile-styler.ts","lineNumber":260,"sourceCode":"      'paddingBottom',\n      calc(`${this.getTileSpan(this.baseTileHeight)} + ${this.getGutterSpan()}`),\n    ];\n  }\n\n  reset(list: TileStyleTarget) {\n    list._setListStyle(['paddingBottom', null]);\n\n    list._tiles.forEach(tile => {\n      tile._setStyle('marginTop', null);\n      tile._setStyle('paddingTop', null);\n    });\n  }\n\n  private _parseRatio(value: string): void {\n    const ratioParts = value.split(':');\n\n    if (ratioParts.length !== 2 && (typeof ngDevMode === 'undefined' || ngDevMode)) {\n      throw Error(`mat-grid-list: invalid ratio given for row-height: \"${value}\"`);\n    }\n\n    this.rowHeightRatio = parseFloat(ratioParts[0]) / parseFloat(ratioParts[1]);\n  }\n}\n\n/**\n * This type of styler is instantiated when the user selects a \"fit\" row height mode.\n * In other words, the row height will reflect the total height of the container divided\n * by the number of rows.  Example `<mat-grid-list cols=\"3\" rowHeight=\"fit\">`\n *\n * @docs-private\n */\nexport class FitTileStyler extends TileStyler {\n  setRowStyles(tile: MatGridTile, rowIndex: number): void {\n    // Percent of the available vertical space that one row takes up.\n    let percentHeightPerTile = 100 / this._rowspan;\n","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/angular/components/blob/0411926e7d8ae06b32236ec1048a888cfad5abf2/src/material/grid-list/tile-styler.ts#L242-L278","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n<mat-grid-list cols=\"3\" rowHeight=\"1\">\n// after\n<mat-grid-list cols=\"3\" rowHeight=\"1:1\"></mat-grid-list>","handlingStrategy":"validation","validationCode":"function isRatioRowHeight(v: string): boolean {\n  return v.split(':').length === 2 && v.split(':').every(p => p.trim() !== '' && !isNaN(Number(p)));\n}","typeGuard":"function isRatioString(v: unknown): v is `${number}:${number}` {\n  return typeof v === 'string' && /^\\d+(\\.\\d+)?:\\d+(\\.\\d+)?$/.test(v);\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["angular-material","grid-list","row-height","invalid-input"],"backgroundTag":"invalid-ratio-format","analyzedSha":"0411926e7d8ae06b32236ec1048a888cfad5abf2","analyzedAt":"2026-08-31T11:58:23.400Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}