zed-industries/zed · error

Canvas returned non-finite text metrics

Error message

Canvas returned non-finite text metrics

What it means

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.

Solutions

  1. 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.
  2. Check that the text being measured is non-empty or handle empty input before calling measure.
  3. Update the browser/WebView; some older or headless browsers return NaN bounding-box metrics.
  4. Wrap the call and fall back to approximate metrics (e.g. advance = 0 or font-size-based estimate) if the error is hit.

Example fix

// before
let metrics = measure(text, "font-size: 16px; family: Inter")?;
// after
let metrics = measure(text, "16px Inter")?;
Defensive patterns

Strategy: validation

Validate before calling

fn is_valid_canvas_font(font: &str) -> bool {
    !font.trim().is_empty() && font.contains("px") && !text.trim().is_empty()
}
if is_valid_canvas_font(css_font) {
    let metrics = measure(text, css_font)?;
}

Type guard

fn finite_metrics(m: &CanvasTextMetrics) -> bool {
    [m.advance, m.left, m.right, m.ascent, m.descent].iter().all(|v| v.is_finite())
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of zed-industries/zed@916fc2b8cb (2026-09-19). Data as JSON: /api/errors/e90500f3a053eced. Report an issue: GitHub.

Appendix: source

Thrown at crates/gpui_web/src/canvas_text.rs:101

        )
    })
}

pub(crate) fn measure(text: &str, css_font: &str) -> Result<CanvasTextMetrics> {
    with_canvas(|canvas| {
        canvas.configure(css_font)?;
        let metrics = canvas
            .context
            .measure_text(text)
            .map_err(|error| anyhow!("measuring Canvas text: {error:?}"))?;
        let metrics = CanvasTextMetrics {
            advance: metrics.width() as f32,
            left: -metrics.actual_bounding_box_left() as f32,
            right: metrics.actual_bounding_box_right() as f32,
            ascent: metrics.actual_bounding_box_ascent() as f32,
            descent: metrics.actual_bounding_box_descent() as f32,
        };
        ensure!(
            [
                metrics.advance,
                metrics.left,
                metrics.right,
                metrics.ascent,
                metrics.descent
            ]
            .into_iter()
            .all(f32::is_finite),
            "Canvas returned non-finite text metrics"
        );
        Ok(metrics)
    })
}

pub(crate) fn rasterize(
    text: &str,
    css_font: &str,

View on GitHub (pinned to 916fc2b8cb)