{"record":{"id":"d300662f31b168bb","repo":"DioxusLabs/dioxus","slug":"the-tree-has-not-been-built-yet-make-sure-to-call","errorCode":null,"errorMessage":"The tree has not been built yet. Make sure to call rebuild on the tree before accessing its nodes.","messagePattern":"The tree has not been built yet\\. Make sure to call rebuild on the tree before accessing its nodes\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/scopes.rs","lineNumber":91,"sourceCode":"pub struct ScopeState {\n    pub(crate) runtime: Rc<Runtime>,\n    pub(crate) context_id: ScopeId,\n    /// The last node that has been rendered for this component. This node may not ben mounted\n    /// During suspense, this component can be rendered in the background multiple times\n    pub(crate) last_rendered_node: Option<LastRenderedNode>,\n    pub(crate) props: BoxedAnyProps,\n    pub(crate) reactive_context: ReactiveContext,\n}\n\nimpl ScopeState {\n    /// Get a handle to the currently active head node arena for this Scope\n    ///\n    /// This is useful for traversing the tree outside of the VirtualDom, such as in a custom renderer or in SSR.\n    ///\n    /// Panics if the tree has not been built yet.\n    pub fn root_node(&self) -> &VNode {\n        self.try_root_node()\n            .expect(\"The tree has not been built yet. Make sure to call rebuild on the tree before accessing its nodes.\")\n    }\n\n    /// Try to get a handle to the currently active head node arena for this Scope\n    ///\n    /// This is useful for traversing the tree outside of the VirtualDom, such as in a custom renderer or in SSR.\n    ///\n    /// Returns [`None`] if the tree has not been built yet.\n    pub fn try_root_node(&self) -> Option<&VNode> {\n        match &self.last_rendered_node {\n            Some(LastRenderedNode::Real(vnode)) => Some(vnode),\n            Some(LastRenderedNode::Placeholder(vnode, _)) => Some(vnode),\n            None => None,\n        }\n    }\n\n    /// Returns the scope id of this [`ScopeState`].\n    pub fn id(&self) -> ScopeId {\n        self.context_id","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/DioxusLabs/dioxus/blob/393d190a801ccb441d41923e232289b4f8a5c669/packages/core/src/scopes.rs#L73-L109","documentation":"ScopeState::root_node() returns the element a scope last rendered, but a freshly constructed VirtualDom has not run a render pass yet, so last_rendered_node is None and the expect panics. The method's docs explicitly state it panics unless the tree has been built. This is a lifecycle error: build the tree before traversing it.","triggerScenarios":"Calling scope.root_node() (custom renderers, SSR walkers, tests, html rendering APIs) on a VirtualDom created with VirtualDom::new but never passed through rebuild()/rebuild_in_place(); accessing root_node before the first render commit.","commonSituations":"Writing a custom renderer or SSR integration and iterating vdom.scopes() before rebuild; unit tests that construct a VirtualDom and immediately inspect its nodes.","solutions":["Call vdom.rebuild_in_place() (or run the rebuild flow in your renderer) before touching scopes","Use scope.try_root_node() and skip scopes that return None instead of root_node()","For suspended scopes, wait until they resolve before traversal"],"exampleFix":"// before\nlet vdom = VirtualDom::new(App);\nlet node = vdom.scopes()[0].root_node(); // panics\n// after\nlet mut vdom = VirtualDom::new(App);\nvdom.rebuild_in_place();\nlet node = vdom.scopes()[0].root_node();","handlingStrategy":"validation","validationCode":"// Guard traversal with the non-panicking variant:\nfor scope in vdom.scopes() {\n    if let Some(root) = scope.try_root_node() {\n        visit(root);\n    } // skip scopes not built yet (e.g. suspended)\n}","typeGuard":"fn scope_is_built(scope: &dioxus_core::ScopeState) -> bool {\n    scope.try_root_node().is_some()\n}","tryCatchPattern":null,"preventionTips":["Always run rebuild_in_place() (or your renderer's rebuild flow) right after VirtualDom::new before traversal","Prefer try_root_node() in generic/renderer code; reserve root_node() for contexts you know are post-render","In tests, make rebuild part of the standard vdom construction helper"],"tags":["virtualdom","core","ssr","renderer","lifecycle","panic"],"backgroundTag":null,"analyzedSha":"393d190a801ccb441d41923e232289b4f8a5c669","analyzedAt":"2026-08-16T11:27:45.815Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}