zed-industries/zed · error

reading Canvas text raster pixels

Error message

reading Canvas text raster pixels: {error:?}

What it means

Thrown in rasterize() when canvas.context.get_image_data(0, 0, width, height) throws or rejects while reading back the freshly drawn pixels from the text canvas. The text was drawn (fill_text succeeded) but the pixel readback failed — commonly a SecurityError from tainted-canvas restrictions or a browser error from an invalid/out-of-bounds readback region, meaning the raster buffer for this text run cannot be produced.

Solutions

  1. Retry the readback once with a freshly created OffscreenCanvas (a single canvas reused across frames can accumulate readback failures)
  2. Fall back to a blank raster of the expected byte size so the glyph slot stays allocated without visible text
  3. Log the JsValue via js_sys::Error::from to distinguish SecurityError (tainted canvas — check that no cross-origin content touched the canvas) from size errors (verify width/height match the canvas dimensions)
  4. Assert width/height exactly equal canvas.width/height before calling get_image_data, since a mismatch throws an IndexSizeError
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at crates/gpui_web/src/canvas_text.rs:176 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

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

        if canvas.canvas.height() != height {
            canvas.canvas.set_height(height);
        }
        canvas.configure(css_font)?;
        canvas
            .context
            .clear_rect(0.0, 0.0, f64::from(width), f64::from(height));
        canvas
            .context
            .fill_text(
                text,
                -f64::from(bounds.origin.x.0) + f64::from(subpixel_offset.0),
                -f64::from(bounds.origin.y.0) + f64::from(subpixel_offset.1),
            )
            .map_err(|error| anyhow!("drawing Canvas text: {error:?}"))?;
        let image = canvas
            .context
            .get_image_data(0.0, 0.0, f64::from(width), f64::from(height))
            .map_err(|error| anyhow!("reading Canvas text raster pixels: {error:?}"))?;
        let mut pixels = image.data().0;
        ensure!(
            pixels.len() == byte_count,
            "Canvas text raster returned {} bytes, expected {byte_count}",
            pixels.len()
        );
        if color {
            for pixel in pixels.chunks_exact_mut(4) {
                pixel.swap(0, 2);
            }
            Ok(pixels)
        } else {
            let mut alpha = Vec::new();
            alpha
                .try_reserve_exact(pixel_count)
                .context("allocating Canvas text alpha mask")?;
            alpha.extend(pixels.chunks_exact(4).map(|pixel| pixel[3]));
            Ok(alpha)

View on GitHub (pinned to 916fc2b8cb)