{"record":{"id":"8a39307c7333c398","repo":"swc-project/swc","slug":"failed-to-parse-namespace-of-context-element","errorCode":null,"errorMessage":"failed to parse namespace of context element","messagePattern":"failed to parse namespace of context element","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"bindings/binding_html_node/src/lib.rs","lineNumber":234,"sourceCode":"        Ok(output)\n    }\n}\n\nenum DocumentOrDocumentFragment {\n    Document(Document),\n    DocumentFragment(DocumentFragment),\n}\n\nfn create_namespace(namespace: &str) -> anyhow::Result<Namespace> {\n    match &*namespace.to_lowercase() {\n        \"http://www.w3.org/1999/xhtml\" => Ok(Namespace::HTML),\n        \"http://www.w3.org/1998/math/mathml\" => Ok(Namespace::MATHML),\n        \"http://www.w3.org/2000/svg\" => Ok(Namespace::SVG),\n        \"http://www.w3.org/1999/xlink\" => Ok(Namespace::XLINK),\n        \"http://www.w3.org/xml/1998/namespace\" => Ok(Namespace::XML),\n        \"http://www.w3.org/2000/xmlns/\" => Ok(Namespace::XMLNS),\n        _ => {\n            bail!(\"failed to parse namespace of context element\")\n        }\n    }\n}\n\nfn create_element(context_element: Element) -> anyhow::Result<swc_html_ast::Element> {\n    let mut attributes = Vec::with_capacity(context_element.attributes.len());\n\n    for attribute in context_element.attributes.into_iter() {\n        let namespace = match attribute.namespace {\n            Some(namespace) => Some(create_namespace(&namespace)?),\n            _ => None,\n        };\n\n        attributes.push(swc_html_ast::Attribute {\n            span: DUMMY_SP,\n            namespace,\n            prefix: attribute.prefix.map(|value| value.into()),\n            name: attribute.name.into(),","sourceCodeStart":216,"sourceCodeEnd":252,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/bindings/binding_html_node/src/lib.rs#L216-L252","documentation":"The HTML Node binding converts the JS-side context element (used for fragment parsing) into a swc_html_ast::Element via create_namespace, which accepts exactly six well-known namespace URIs (XHTML, MathML, SVG, XLINK, XML, XMLNS), compared after to_lowercase(). Any other namespace string on the context element or one of its attributes fails here, before parsing starts. The check is exact string matching, so a trailing slash or typo is enough.","triggerScenarios":"Calling the HTML parse API in fragment mode with options.contextElement whose namespace (or an attribute's namespace) is not one of the six URIs, e.g. 'http://www.w3.org/2000/svg/' (trailing slash), 'https://www.w3.org/2000/svg' (https), or a custom namespace like 'http://example.com/ns'.","commonSituations":"Copy-pasted namespace URIs with typos or trailing slashes; XML-first pipelines emitting custom xmlns declarations into the context element; TypeScript users assuming any string is fine because the binding types namespace as plain string; case differences are tolerated (lowercased) but scheme/slash differences are not.","solutions":["Use exactly one of the six URIs: 'http://www.w3.org/1999/xhtml', 'http://www.w3.org/1998/math/mathml', 'http://www.w3.org/2000/svg', 'http://www.w3.org/1999/xlink', 'http://www.w3.org/xml/1998/namespace', 'http://www.w3.org/2000/xmlns/' (note: only xmlns ends with a slash)","Omit the namespace field entirely when the element or attribute has no namespace","Map or strip custom namespaces in your own code before passing the context element to the binding"],"exampleFix":"// before\nconst res = parseSync(src, {\n  contextElement: {\n    tagName: 'svg',\n    namespace: 'http://www.w3.org/2000/svg/', // trailing slash -> bail\n  },\n});\n\n// after\nconst res = parseSync(src, {\n  contextElement: {\n    tagName: 'svg',\n    namespace: 'http://www.w3.org/2000/svg',\n  },\n});","handlingStrategy":"validation","validationCode":"const KNOWN_NAMESPACES = new Set([\n  'http://www.w3.org/1999/xhtml',\n  'http://www.w3.org/1998/math/mathml',\n  'http://www.w3.org/2000/svg',\n  'http://www.w3.org/1999/xlink',\n  'http://www.w3.org/xml/1998/namespace',\n  'http://www.w3.org/2000/xmlns/',\n]);\nfunction normalizeNamespace(ns) {\n  if (ns == null) return undefined;\n  const lower = ns.toLowerCase();\n  if (!KNOWN_NAMESPACES.has(lower)) {\n    throw new RangeError(`unsupported namespace: ${ns}`);\n  }\n  return lower;\n}\ncontextElement.namespace = normalizeNamespace(contextElement.namespace);","typeGuard":"const isKnownNamespace = (ns: string): boolean =>\n  new Set([\n    'http://www.w3.org/1999/xhtml',\n    'http://www.w3.org/1998/math/mathml',\n    'http://www.w3.org/2000/svg',\n    'http://www.w3.org/1999/xlink',\n    'http://www.w3.org/xml/1998/namespace',\n    'http://www.w3.org/2000/xmlns/',\n  ]).has(ns.toLowerCase());","tryCatchPattern":"try {\n  const res = parseSync(src, { contextElement });\n} catch (e) {\n  if (String(e?.message).includes('namespace of context element')) {\n    return parseSync(src, { contextElement: stripNamespaces(contextElement) });\n  }\n  throw e;\n}","preventionTips":["Store namespace URIs as named constants instead of inline strings","Only 'http://www.w3.org/2000/xmlns/' ends with a slash - copy the six URIs exactly","Run context elements coming from other parsers through a namespace allowlist"],"tags":["swc","html","namespace","context-element","node-bindings"],"backgroundTag":"unknown-namespace-uri","analyzedSha":"5176682b65416c6b5de6b47379ae1588ea3ecb3f","analyzedAt":"2026-08-17T16:16:52.067Z","contentChangedAt":"2026-08-17T16:16:52.067Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}