yewstack/yew · error

can't create namespaced element for vtag

Error message

can't create namespaced element for vtag

What it means

VTag::create_element (packages/yew/src/dom_bundle/btag/mod.rs:270) honors an explicit xmlns attribute: its string value is passed straight to document().create_element_ns as the namespace, with the result unwrapped by .expect. create_element_ns throws NamespaceError for invalid namespace URIs (empty string, whitespace-containing, or otherwise malformed) and InvalidCharacterError for an invalid qualified tag name — so a bogus xmlns value on any element panics here.

Source

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

        DomSlot::at(el.clone().into())
    }
}

impl VTag {
    fn create_element(&self, parent: &Element) -> Element {
        let tag = self.tag();
        // check for an xmlns attribute. If it exists, create an element with the specified
        // namespace
        match self
            .attributes
            .iter()
            .find(|(k, _)| *k == "xmlns")
            .map(|(_, v)| v)
        {
            Some(xmlns) => document()
                .create_element_ns(Some(xmlns), tag)
                .expect("can't create namespaced element for vtag"),
            _ => {
                if tag == "svg" || parent.namespace_uri().is_some_and(|ns| ns == SVG_NAMESPACE) {
                    let namespace = Some(SVG_NAMESPACE);
                    document()
                        .create_element_ns(namespace, tag)
                        .expect("can't create namespaced element for vtag")
                } 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));

View on GitHub (pinned to 0e4a05472f)

Solutions

  1. Use the exact canonical namespace URIs (http://www.w3.org/2000/svg, http://www.w3.org/1998/Math/MathML) or a syntactically valid absolute URI for custom namespaces
  2. Never pass an empty xmlns; omit the attribute entirely to let Yew's svg/math detection pick the namespace
  3. Validate the xmlns value at the boundary if it comes from user/config data

Example fix

// before
html! { <f:math xmlns="mathml"> { children } </f:math> }

// after
html! { <math xmlns="http://www.w3.org/1998/Math/MathML"> { children } </math> }
Defensive patterns

Strategy: validation

Validate before calling

fn is_valid_namespace(uri: &str) -> bool {
    !uri.is_empty() && !uri.chars().any(char::is_whitespace) && uri.contains(':')
}

const SVG: &str = "http://www.w3.org/2000/svg";
const MATHML: &str = "http://www.w3.org/1998/Math/MathML";
// before: <custom xmlns={user_ns}>  ->  assert is_valid_namespace(user_ns)

Type guard

fn known_namespace(tag: &str) -> Option<&'static str> {
    match tag { "svg" => Some("http://www.w3.org/2000/svg"), "math" => Some("http://www.w3.org/1998/Math/MathML"), _ => None }
}

Prevention

When it happens

Trigger: Writing html! { <mytag xmlns="not a uri"> } (space in URI), xmlns="" (empty namespace), or an xmlns value copied with a typo (e.g. a trailing character in the SVG/MathML URLs on a non-svg tag name the code does not special-case).

Common situations: Custom XML vocabularies embedded in Yew trees; copy-pasted namespace constants from docs that got mangled; user-provided namespace strings passed through configuration.

Related errors


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