zed-industries/zed · error

A11ySubtreeBuilder exists only while its element's node is o

Error message

A11ySubtreeBuilder exists only while its element's node is on the stack

What it means

A11ySubtreeBuilder::parent_node expects a current node on the accesskit node stack; the builder only exists while its element's node is pushed. Panicking means parent_node was called when no node is active — builder used outside its element's push/pop scope or unbalanced pushes/pops.

Source

Thrown at crates/gpui/src/window/a11y.rs:363

        if pushed {
            self.nodes.record_node_info(
                id,
                debug::NodeDebugInfo {
                    synthetic: true,
                    view: self.creator.view,
                    element_id: self.creator.element_id.clone(),
                    source_location: self.creator.source_location,
                },
            );
        }
        pushed
    }

    /// A mutable reference to the parent node.
    pub fn parent_node(&mut self) -> &mut accesskit::Node {
        self.nodes
            .current_node_mut()
            .expect("A11ySubtreeBuilder exists only while its element's node is on the stack")
    }
}

pub(crate) struct A11yNodeBuilder {
    ids_stack: SmallVec<[NodeId; 16]>,
    nodes_stack: SmallVec<[accesskit::Node; 16]>,
    /// This is the exact type required by accesskit, so we can't just make it a
    /// `HashMap<NodeId, Node>` to remove the need for `seen_ids`
    all_nodes: Vec<(NodeId, accesskit::Node)>,
    seen_ids: FxHashSet<NodeId>,
    /// The node that GPUI considers focused. Note that this may be different to
    /// what is reported to accesskit - see [`Self::active_descendant`]
    focus: Option<NodeId>,
    /// If a node calls `.aria_active_descendant()`, AND an ancestor is focused,
    /// override it as the focused node. This supports the "active descendant"
    /// pattern, which allows a focused container to act as if a descendant is
    /// focused.
    active_descendant: Option<NodeId>,

View on GitHub (pinned to f4178619ac)

Solutions

  1. Only call parent_node between the matching push of the element's node and its pop
  2. Check push/pop pairing, especially around early returns in accessibility tree building
  3. Verify the builder isn't retained beyond its element's subtree construction
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at crates/gpui/src/window/a11y.rs:363 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20). Data as JSON: /api/errors/36b209f78ddd7e7c. Report an issue: GitHub.