{"record":{"id":"e90500f3a053eced","repo":"zed-industries/zed","slug":"canvas-returned-non-finite-text-metrics","errorCode":null,"errorMessage":"Canvas returned non-finite text metrics","messagePattern":"Canvas returned non-finite text metrics","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/gpui_web/src/canvas_text.rs","lineNumber":101,"sourceCode":"        )\n    })\n}\n\npub(crate) fn measure(text: &str, css_font: &str) -> Result<CanvasTextMetrics> {\n    with_canvas(|canvas| {\n        canvas.configure(css_font)?;\n        let metrics = canvas\n            .context\n            .measure_text(text)\n            .map_err(|error| anyhow!(\"measuring Canvas text: {error:?}\"))?;\n        let metrics = CanvasTextMetrics {\n            advance: metrics.width() as f32,\n            left: -metrics.actual_bounding_box_left() as f32,\n            right: metrics.actual_bounding_box_right() as f32,\n            ascent: metrics.actual_bounding_box_ascent() as f32,\n            descent: metrics.actual_bounding_box_descent() as f32,\n        };\n        ensure!(\n            [\n                metrics.advance,\n                metrics.left,\n                metrics.right,\n                metrics.ascent,\n                metrics.descent\n            ]\n            .into_iter()\n            .all(f32::is_finite),\n            \"Canvas returned non-finite text metrics\"\n        );\n        Ok(metrics)\n    })\n}\n\npub(crate) fn rasterize(\n    text: &str,\n    css_font: &str,","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/zed-industries/zed/blob/916fc2b8cb3a815cbef4a3b40e13081be72036b6/crates/gpui_web/src/canvas_text.rs#L83-L119","documentation":"gpui_web's `measure` calls the browser Canvas 2D `measureText` API and converts the returned TextMetrics (width, bounding box, ascent, descent) into f32 values. This error is thrown when any of those metrics is NaN or infinite, meaning the browser produced unusable measurements. The library throws it defensively because non-finite metrics would corrupt glyph layout and raster bounds downstream.","triggerScenarios":"Calling `measure(text, css_font)` when the canvas 2D context returns non-finite TextMetrics: e.g. a malformed or empty CSS font string that the browser silently ignores leaving an undefined font state, measure_text called before a valid font is configured, or browser bugs (certain headless/embedded browsers) returning NaN for actual_bounding_box_* on empty or whitespace-only strings.","commonSituations":"WASM builds running in unusual browsers or embedded WebViews (e.g. headless Chromium during tests, Electron with disabled font rendering) where measureText returns NaN; passing a font string with unsupported units (e.g. `font-size: 16px` CSS shorthand instead of the canvas `16px sans-serif` form); measuring an empty string on a context whose font failed to apply.","solutions":["Validate the css_font string is a valid canvas font spec (e.g. `\"16px Inter\"`, not a CSS `font:` shorthand with unsupported parts) before calling measure.","Check that the text being measured is non-empty or handle empty input before calling measure.","Update the browser/WebView; some older or headless browsers return NaN bounding-box metrics.","Wrap the call and fall back to approximate metrics (e.g. advance = 0 or font-size-based estimate) if the error is hit."],"exampleFix":"// before\nlet metrics = measure(text, \"font-size: 16px; family: Inter\")?;\n// after\nlet metrics = measure(text, \"16px Inter\")?;","handlingStrategy":"validation","validationCode":"fn is_valid_canvas_font(font: &str) -> bool {\n    !font.trim().is_empty() && font.contains(\"px\") && !text.trim().is_empty()\n}\nif is_valid_canvas_font(css_font) {\n    let metrics = measure(text, css_font)?;\n}","typeGuard":"fn finite_metrics(m: &CanvasTextMetrics) -> bool {\n    [m.advance, m.left, m.right, m.ascent, m.descent].iter().all(|v| v.is_finite())\n}","tryCatchPattern":null,"preventionTips":["Always pass canvas-style font strings (`16px Inter`), not CSS font shorthand.","Never call measure with an empty text buffer; guard empty input.","Test text measurement in the actual target browser/WebView early."],"tags":["canvas","text-measurement","wasm","non-finite"],"backgroundTag":"unexpected-response-shape","analyzedSha":"916fc2b8cb3a815cbef4a3b40e13081be72036b6","analyzedAt":"2026-09-19T19:09:50.599Z","contentChangedAt":"2026-09-19T19:09:50.599Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}