yewstack/yew · error

couldn't clone cached element

Error message

couldn't clone cached element

What it means

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).

Source

Thrown at packages/yew/src/dom_bundle/btag/mod.rs:295

                } else if tag == "math"
                    || parent
                        .namespace_uri()
                        .is_some_and(|ns| ns == MATHML_NAMESPACE)
                {
                    let namespace = Some(MATHML_NAMESPACE);
                    document()
                        .create_element_ns(namespace, tag)
                        .expect("can't create namespaced element for vtag")
                } else {
                    thread_local! {
                        static CACHED_ELEMENTS: RefCell<HashMap<String, Element>> = RefCell::new(HashMap::with_capacity(32));
                    }

                    CACHED_ELEMENTS.with(|cache| {
                        let mut cache = cache.borrow_mut();
                        let cached = cache.get(tag).map(|el| {
                            el.clone_node()
                                .expect("couldn't clone cached element")
                                .unchecked_into::<Element>()
                        });
                        cached.unwrap_or_else(|| {
                            let to_be_cached = document()
                                .create_element(tag)
                                .expect("can't create element for vtag");
                            cache.insert(
                                tag.to_string(),
                                to_be_cached
                                    .clone_node()
                                    .expect("couldn't clone node to be cached")
                                    .unchecked_into(),
                            );
                            to_be_cached
                        })
                    })
                }
            }

View on GitHub (pinned to 0e4a05472f)

Solutions

  1. Open the browser console and read the DOMException printed under the panic - it states the real reason cloneNode failed
  2. If a custom element is involved, make its constructor tolerate being cloned while disconnected (skip initialization when this.isConnected is false)
  3. 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
  4. 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

Example fix

// before (JS): constructor throws when cloned disconnected
customElements.define('x-widget', class extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: 'open' }); // may throw on cloned, disconnected nodes in some engines
    doInit(this);
  }
});

// after: tolerate the clone Yew performs for its template cache
customElements.define('x-widget', class extends HTMLElement {
  constructor() {
    super();
    if (this.isConnected) {
      doInit(this);
    }
  }
});
Defensive patterns

Strategy: validation

Validate before calling

// In the browser console, verify a tag clones cleanly before Yew caches it:
// document.createElement('x-widget').cloneNode()
// If that throws, fix the element definition before rendering it through Yew.

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of yewstack/yew@0e4a05472f (2026-08-22). Data as JSON: /api/errors/b5d111faa85a8f33. Report an issue: GitHub.