{"record":{"id":"0e0a12434ef7ea60","repo":"yewstack/yew","slug":"failed-to-clone-node","errorCode":null,"errorMessage":"failed to clone node.","messagePattern":"failed to clone node\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/yew/src/dom_bundle/fragment.rs","lineNumber":142,"sourceCode":"\n    /// Remove child nodes until first non-text node.\n    pub fn trim_start_text_nodes(&mut self) {\n        while let Some(ref m) = self.front().cloned() {\n            if m.node_type() == Node::TEXT_NODE {\n                self.pop_front();\n\n                m.unchecked_ref::<web_sys::Text>().remove();\n            } else {\n                break;\n            }\n        }\n    }\n\n    /// Deeply clones all nodes.\n    pub fn deep_clone(&self) -> Self {\n        let nodes = self\n            .iter()\n            .map(|m| m.clone_node_with_deep(true).expect(\"failed to clone node.\"))\n            .collect::<VecDeque<_>>();\n\n        // the cloned nodes are disconnected from the real dom, so next_child is `None`\n        Self(nodes, None)\n    }\n\n    // detaches current fragment.\n    pub fn detach(self, _root: &BSubtree, parent: &Element, parent_to_detach: bool) {\n        if !parent_to_detach {\n            for node in self.iter() {\n                parent\n                    .remove_child(node)\n                    .expect(\"failed to remove child element\");\n            }\n        }\n    }\n\n    /// Shift current Fragment into a different position in the dom.","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/yewstack/yew/blob/0e4a05472fac4e5fce1befe60fa4a1e43a36b6a3/packages/yew/src/dom_bundle/fragment.rs#L124-L160","documentation":"During hydration, Yew re-parents server-rendered nodes and deep-clones each node of a fragment with clone_node_with_deep(true); this expect fires when the browser refuses to deep-clone one of those nodes. Because Yew itself created or adopted these nodes, a failure normally comes from page content that does not survive a deep clone - custom elements whose constructors throw, or node types with clone restrictions in the target engine - rather than from component logic.","triggerScenarios":"Calling Renderer::hydrate() over SSR HTML whose hydrated region contains web components with throwing constructors or other non-clonable nodes; hydration inside engines with partial cloneNode(true) support.","commonSituations":"Third-party widgets (editors, maps, analytics) embedded in server-rendered pages that are later hydrated; older mobile webviews; SSR output that injected unusual nodes into the tree.","solutions":["Bisect the page: hydrate progressively smaller subtrees until the failing element is isolated","Test the suspect markup in the console with document.querySelector('<sel>').cloneNode(true) - a throw identifies the culprit","Move the non-clonable widget outside the hydrated region and mount it client-side after hydration completes","If an ordinary element fails to deep-clone, file a Yew issue with the SSR HTML and a repro"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before hydrating a page containing third-party widgets, verify the markup clones:\n// document.querySelector('#widget-host').cloneNode(true)\n// If that throws in the console, exclude the region from hydration.","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep web components and other exotic nodes outside the hydrated region; mount them client-side after hydration","Smoke-test cloneNode(true) on SSR output when adding new third-party markup","Prefer hydrating regions that contain only standard HTML produced by your own components"],"tags":["hydration","ssr","dom","clone-node"],"backgroundTag":"dom-node-clone-failed","analyzedSha":"0e4a05472fac4e5fce1befe60fa4a1e43a36b6a3","analyzedAt":"2026-08-22T21:16:31.212Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}