zed-industries/zed · error
Canvas text font is empty
Error message
Canvas text font is empty
What it means
Raised in `TextCanvas::configure` when the CSS font string passed for canvas text rendering is empty or whitespace-only. Canvas silently ignores empty/invalid font assignments, so the library fails fast with a clear error instead of rendering text with a stale or default font. Called from `intercept_debug_sessions` during canvas text setup.
Solutions
- Ensure the font style resolves to a non-empty CSS font string before calling configure
- Check the font-family/font-size inputs feeding this code path (e.g. theme settings, buffer font config)
- Add a default fallback font (e.g. '12px sans-serif') when resolution produces an empty value
- Log the incoming css_font value to find which caller passes an empty string
Example fix
// before
canvas.configure(&css_font);
// after
let css_font = if css_font.trim().is_empty() {
"12px sans-serif".to_string()
} else {
css_font
};
canvas.configure(&css_font); Defensive patterns
Strategy: validation
Validate before calling
fn ensure_css_font(css_font: &str) -> Result<()> {
anyhow::ensure!(!css_font.trim().is_empty(), "font must be a non-empty CSS font string");
Ok(())
}
// call ensure_css_font(&font)? before canvas.configure(&font); Type guard
fn is_valid_css_font(css_font: &str) -> bool {
!css_font.trim().is_empty()
} Try / catch
match canvas.configure(&css_font) {
Err(e) if e.to_string().contains("font is empty") => {
canvas.configure("12px sans-serif")? // fallback font
}
Err(e) => return Err(e),
Ok(()) => (),
} Prevention
- Resolve fonts to a concrete CSS string (family + size + weight) before text measurement
- Provide a default/fallback font at the theme/config layer
- Fail or default early when font resolution returns empty rather than passing empty strings downward
- Add a unit test asserting the style-to-CSS-font conversion never yields an empty string
When it happens
Trigger: Passing an empty string, a string of only spaces, or an unset/None-defaulted font value into the canvas text configuration path (e.g. `configure("")` or a font style that resolved to nothing).
Common situations: Font resolution failing upstream so an empty CSS font string reaches the canvas, theme/font configuration missing a font-family entry, or text style defaults not being populated before text layout runs.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Canvas readback option could not be set
- Canvas returned non-finite text metrics
- Canvas text direction could not be set
- Canvas text raster exceeds maximum dimension
- Canvas text raster exceeds maximum pixel count
AI-assisted analysis of zed-industries/zed@916fc2b8cb (2026-09-19).
Data as JSON: /api/errors/deda419e9f47c9f6.
Report an issue: GitHub.
Appendix: source
Thrown at crates/gpui_web/src/canvas_text.rs:51
// Every rasterized glyph is read back for upload into GPUI's atlas.
let assigned = js_sys::Reflect::set(
&options,
&JsValue::from_str("willReadFrequently"),
&JsValue::TRUE,
)
.map_err(|error| anyhow!("setting Canvas readback option: {error:?}"))?;
ensure!(assigned, "Canvas readback option could not be set");
let context = canvas
.get_context_with_context_options("2d", &options)
.map_err(|error| anyhow!("getting OffscreenCanvas 2D context: {error:?}"))?
.context("OffscreenCanvas 2D text rendering is unavailable")?
.dyn_into::<OffscreenCanvasRenderingContext2d>()
.map_err(|error| anyhow!("unexpected OffscreenCanvas 2D context: {error:?}"))?;
Ok(Self { canvas, context })
}
fn configure(&self, css_font: &str) -> Result<()> {
ensure!(!css_font.trim().is_empty(), "Canvas text font is empty");
// An invalid CSS font assignment is ignored by Canvas. Reset first so
// it cannot accidentally inherit the preceding request's font.
self.context.set_font("10px sans-serif");
self.context.set_font(css_font);
self.context.set_text_align("left");
self.context.set_text_baseline("alphabetic");
self.context.set_fill_style_str("white");
// web-sys does not expose direction on the offscreen 2D context.
let assigned = js_sys::Reflect::set(
self.context.as_ref(),
&JsValue::from_str("direction"),
&JsValue::from_str("ltr"),
)
.map_err(|error| anyhow!("setting Canvas text direction: {error:?}"))?;
ensure!(assigned, "Canvas text direction could not be set");
Ok(())
}
}View on GitHub (pinned to 916fc2b8cb)