zed-industries/zed · error

Missing root

Error message

Missing root

What it means

A sentinel guard in WebViewport::update: after obtaining the document, document.documentElement() returned None, so the viewport cannot read the root <html> element it needs for layout and inset measurements. Like the missing-document case this realistically occurs during teardown or in malformed/non-HTML documents; the frame's bounds update is aborted.

Source

Thrown at crates/gpui_web/src/viewport.rs:54

        // Separate boxes detect redistribution between edges even when the
        // total inset, and therefore a single combined probe's size, is unchanged.
        for probe in &self.safe_area_probes {
            observer.observe(probe);
        }
    }

    pub(crate) fn update(
        &mut self,
        window: &web_sys::Window,
        canvas: &web_sys::HtmlCanvasElement,
    ) -> anyhow::Result<bool> {
        let canvas_bounds = canvas.get_bounding_client_rect();
        let document = window
            .document()
            .ok_or_else(|| anyhow::anyhow!("Missing document"))?;
        let root = document
            .document_element()
            .ok_or_else(|| anyhow::anyhow!("Missing root"))?;
        let layout_width = root.client_width() as f64;
        let layout_height = root.client_height() as f64;
        let (left, top, width, height) = match window.visual_viewport() {
            Some(viewport) => (
                viewport.offset_left(),
                viewport.offset_top(),
                viewport.width(),
                viewport.height(),
            ),
            None => (0., 0., layout_width, layout_height),
        };
        // VisualViewport offsets and getBoundingClientRect share layout CSS
        // coordinates. Multiplying by the pinch scale here would incorrectly
        // expand the visible rectangle back to its unzoomed size.
        let x = (left - canvas_bounds.left()).clamp(0., canvas_bounds.width());
        let y = (top - canvas_bounds.top()).clamp(0., canvas_bounds.height());
        let right = (left + width - canvas_bounds.left()).clamp(x, canvas_bounds.width());
        let bottom = (top + height - canvas_bounds.top()).clamp(y, canvas_bounds.height());

View on GitHub (pinned to 9d272b0363)

Solutions

  1. Skip the update for this frame and reuse cached bounds when the root element is momentarily unavailable
  2. Avoid calling update during unload/teardown of the page
  3. Verify the served document is well-formed HTML with an <html> root element
Defensive patterns

Strategy: fallback

When it happens

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

Common situations: See trigger scenarios.


AI-assisted analysis of zed-industries/zed@9d272b0363 (2026-09-12). Data as JSON: /api/errors/f317fb3a35e28903. Report an issue: GitHub.