{"record":{"id":"b5d111faa85a8f33","repo":"yewstack/yew","slug":"couldn-t-clone-cached-element","errorCode":null,"errorMessage":"couldn't clone cached element","messagePattern":"couldn't clone cached element","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/yew/src/dom_bundle/btag/mod.rs","lineNumber":295,"sourceCode":"                } else if tag == \"math\"\n                    || parent\n                        .namespace_uri()\n                        .is_some_and(|ns| ns == MATHML_NAMESPACE)\n                {\n                    let namespace = Some(MATHML_NAMESPACE);\n                    document()\n                        .create_element_ns(namespace, tag)\n                        .expect(\"can't create namespaced element for vtag\")\n                } else {\n                    thread_local! {\n                        static CACHED_ELEMENTS: RefCell<HashMap<String, Element>> = RefCell::new(HashMap::with_capacity(32));\n                    }\n\n                    CACHED_ELEMENTS.with(|cache| {\n                        let mut cache = cache.borrow_mut();\n                        let cached = cache.get(tag).map(|el| {\n                            el.clone_node()\n                                .expect(\"couldn't clone cached element\")\n                                .unchecked_into::<Element>()\n                        });\n                        cached.unwrap_or_else(|| {\n                            let to_be_cached = document()\n                                .create_element(tag)\n                                .expect(\"can't create element for vtag\");\n                            cache.insert(\n                                tag.to_string(),\n                                to_be_cached\n                                    .clone_node()\n                                    .expect(\"couldn't clone node to be cached\")\n                                    .unchecked_into(),\n                            );\n                            to_be_cached\n                        })\n                    })\n                }\n            }","sourceCodeStart":277,"sourceCodeEnd":313,"githubUrl":"https://github.com/yewstack/yew/blob/0e4a05472fac4e5fce1befe60fa4a1e43a36b6a3/packages/yew/src/dom_bundle/btag/mod.rs#L277-L313","documentation":"Yew keeps a thread-local cache of template DOM elements (CACHED_ELEMENTS in packages/yew/src/dom_bundle/btag/mod.rs:288) and builds new nodes for plain (non-namespaced, non-SVG/MathML) tags by cloning the cached template with el.clone_node(). This expect fires when the browser rejects that clone. Cloning a detached element created by Yew is an internal invariant that standard browsers uphold, so hitting this usually means the cached template was poisoned - most often a custom element whose constructor throws while being cloned disconnected, or an element owned by a document that is no longer usable (e.g. a removed iframe).","triggerScenarios":"Rendering a standard VTag (div, span, custom-element name, without xmlns) whose tag name is already in the template cache, where cloneNode() on the cached element returns an error - e.g. a component registered via customElements.define whose constructor throws when cloned while not connected, or cached elements belonging to a destroyed foreign document.","commonSituations":"Apps using web components with stateful constructors that assume layout or connectivity; Yew mounted inside an iframe that gets destroyed and recreated while the thread-local cache survives; embedded webviews with partial DOM implementations; rarely, Yew regressions between versions.","solutions":["Open the browser console and read the DOMException printed under the panic - it states the real reason cloneNode failed","If a custom element is involved, make its constructor tolerate being cloned while disconnected (skip initialization when this.isConnected is false)","Ensure the whole app creates elements from one Document - never feed elements from document.implementation.create_html_document or another iframe's document into Yew","If plain tags like div/span trigger it with no custom elements involved, file a Yew issue with the panic stack and your yew/wasm-bindgen versions"],"exampleFix":"// before (JS): constructor throws when cloned disconnected\ncustomElements.define('x-widget', class extends HTMLElement {\n  constructor() {\n    super();\n    this.attachShadow({ mode: 'open' }); // may throw on cloned, disconnected nodes in some engines\n    doInit(this);\n  }\n});\n\n// after: tolerate the clone Yew performs for its template cache\ncustomElements.define('x-widget', class extends HTMLElement {\n  constructor() {\n    super();\n    if (this.isConnected) {\n      doInit(this);\n    }\n  }\n});","handlingStrategy":"validation","validationCode":"// In the browser console, verify a tag clones cleanly before Yew caches it:\n// document.createElement('x-widget').cloneNode()\n// If that throws, fix the element definition before rendering it through Yew.","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Do not register custom elements whose constructors throw when cloned while disconnected","Create all Yew-managed DOM from a single Document; avoid mixing in elements from other iframes or created via implementation.create_html_document","Pin a known-good Yew version and retest element creation after upgrades"],"tags":["dom","custom-elements","clone-node","internal-invariant"],"backgroundTag":"dom-node-clone-failed","analyzedSha":"0e4a05472fac4e5fce1befe60fa4a1e43a36b6a3","analyzedAt":"2026-08-22T21:16:31.212Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}