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

  1. Ensure the font style resolves to a non-empty CSS font string before calling configure
  2. Check the font-family/font-size inputs feeding this code path (e.g. theme settings, buffer font config)
  3. Add a default fallback font (e.g. '12px sans-serif') when resolution produces an empty value
  4. 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

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


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)