zed-industries/zed · error
Canvas text raster returned
Error message
Canvas text raster returned {} bytes, expected {byte_count} What it means
After drawing text, `rasterize` reads back the canvas with get_image_data and verifies the returned pixel buffer length equals the expected byte_count (width * height * 4 bytes RGBA). This error is thrown when the browser returned a different number of bytes than requested. Since the canvas is resized to exactly width x height before drawing, a mismatch indicates a browser/implementation inconsistency rather than caller error.
Solutions
- Verify the browser's own canvas size limits (check canvas.width/canvas.height after resize); reduce the raster size below the browser's cap.
- Update the browser/WebView runtime; older OffscreenCanvas implementations have getImageData bugs.
- Retry the rasterize with smaller bounds if the runtime silently clamped the canvas.
- If persistent, log actual vs expected sizes and report the runtime; work around by tiling the raster.
Example fix
// before let image = ctx.get_image_data(0.0, 0.0, width as f64, height as f64)?; // after (caller-side guard) let width = width.min(max_supported_canvas_dimension(&runtime)); let height = height.min(max_supported_canvas_dimension(&runtime)); rasterize(text, font, bounds_with_size(width, height), offset, color)?;
Defensive patterns
Strategy: try-catch
Validate before calling
let pixels = (width as usize) * (height as usize) * 4; // No caller-side pre-check can fully prevent this; the mismatch is browser-side.
Try / catch
match rasterize(text, font, bounds, offset, color) {
Ok(pixels) => upload_to_atlas(pixels),
Err(err) if err.to_string().contains("returned") && err.to_string().contains("bytes") => {
log::warn!("canvas readback size mismatch: {err}; retrying with smaller bounds");
retry_with_tiled_bounds(text, font, bounds, offset, color)
}
Err(err) => return Err(err),
} Prevention
- Keep rasters well below the browser's own canvas dimension caps.
- Target up-to-date browser/WebView runtimes with conformant OffscreenCanvas.
- Treat this error as an environment problem: fall back to tiled/smaller rasters rather than crashing.
When it happens
Trigger: The OffscreenCanvas 2D backend returns an ImageData whose size does not match the get_image_data request — e.g. the canvas resize (set_width/set_height) silently failed or was clamped by the browser (browsers cap canvas size, returning a smaller buffer), or a buggy WebView implementation of OffscreenCanvas getImageData.
Common situations: Browsers or embedded WebViews that silently clamp canvas dimensions below the requested size (some cap total canvas area or max dimension independently); memory-constrained environments where the resize failed; non-conformant OffscreenCanvas implementations in older runtimes.
Related errors
- Canvas text raster exceeds maximum dimension
- Canvas text raster exceeds maximum pixel count
- Canvas text subpixel offset must be finite
- creating text OffscreenCanvas
- getting OffscreenCanvas 2D context
AI-assisted analysis of zed-industries/zed@916fc2b8cb (2026-09-19).
Data as JSON: /api/errors/55dd255eacbfa721.
Report an issue: GitHub.
Appendix: source
Thrown at crates/gpui_web/src/canvas_text.rs:178
}
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)