zed-industries/zed · error

Canvas text subpixel offset must be finite

Error message

Canvas text subpixel offset must be finite

What it means

gpui_web's `rasterize` draws text onto an OffscreenCanvas at a subpixel offset. This error is thrown before any drawing when either component of `subpixel_offset: (f32, f32)` is NaN or infinite. Offsets derived from broken layout math (e.g. division by zero or propagating non-finite text metrics) would be passed to fill_text and produce garbage output, so the library rejects them eagerly.

Solutions

  1. Check the origin of the offset values; fix the upstream layout/positioning code that produced NaN or infinity.
  2. Sanitize the offset at the call site: replace non-finite values with 0.0 or clamp before calling rasterize.
  3. Verify fonts loaded correctly; unloaded fonts often lead to NaN positions from missing metrics.
  4. Reduce scale/zoom factors that may overflow f32 when computing glyph positions.

Example fix

// before
rasterize(text, font, bounds, (position.x, position.y), false)?;
// after
let offset = (if position.x.is_finite() { position.x } else { 0.0 },
              if position.y.is_finite() { position.y } else { 0.0 });
rasterize(text, font, bounds, offset, false)?;
Defensive patterns

Strategy: validation

Validate before calling

if !offset.0.is_finite() || !offset.1.is_finite() {
    return Err(anyhow!("invalid subpixel offset from layout"));
}
rasterize(text, font, bounds, offset, color)?;

Type guard

fn finite_offset(offset: (f32, f32)) -> bool {
    offset.0.is_finite() && offset.1.is_finite()
}

Prevention

When it happens

Trigger: Calling `rasterize` with a subpixel_offset containing NaN or +/-inf — typically produced upstream by non-finite text metrics (see error 50), a division by zero in glyph positioning, or uninitialized glyph run state in the platform text shaper.

Common situations: Rendering after a font failed to load so layout math produced NaN; very large scale factors causing float overflow to infinity in the text system; a bug in an app-level glyph-position calculation passed straight through to rasterize.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

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

                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,
    bounds: Bounds<DevicePixels>,
    subpixel_offset: (f32, f32),
    color: bool,
) -> Result<Vec<u8>> {
    ensure!(
        subpixel_offset.0.is_finite() && subpixel_offset.1.is_finite(),
        "Canvas text subpixel offset must be finite"
    );
    let width = u32::try_from(bounds.size.width.0)
        .context("Canvas text raster width must be nonnegative")?;
    let height = u32::try_from(bounds.size.height.0)
        .context("Canvas text raster height must be nonnegative")?;
    if width == 0 || height == 0 {
        return Ok(Vec::new());
    }
    ensure!(
        width <= MAX_RASTER_DIMENSION && height <= MAX_RASTER_DIMENSION,
        "Canvas text raster exceeds maximum dimension {MAX_RASTER_DIMENSION}: {width}x{height}"
    );
    let pixel_count = usize::try_from(width)?
        .checked_mul(usize::try_from(height)?)
        .context("Canvas text raster pixel count overflow")?;
    ensure!(

View on GitHub (pinned to 916fc2b8cb)