swc-project/swc · error · anyhow::Error
failed to parse namespace of context element
Error message
failed to parse namespace of context element
What it means
Same logic as the Node binding, compiled into the WebAssembly HTML binding: create_namespace accepts exactly six well-known namespace URIs (XHTML, MathML, SVG, XLINK, XML, XMLNS), compared lowercased, when converting the JS-side context element for fragment parsing. Any other namespace string on the element or its attributes fails before parsing begins; the error then crosses the wasm boundary as a JS exception.
Source
Thrown at bindings/binding_html_wasm/src/lib.rs:278
const fn default_collapse_whitespaces() -> CollapseWhitespaces {
CollapseWhitespaces::OnlyMetadata
}
enum DocumentOrDocumentFragment {
Document(Document),
DocumentFragment(DocumentFragment),
}
fn create_namespace(namespace: &str) -> anyhow::Result<Namespace> {
match &*namespace.to_lowercase() {
"http://www.w3.org/1999/xhtml" => Ok(Namespace::HTML),
"http://www.w3.org/1998/math/mathml" => Ok(Namespace::MATHML),
"http://www.w3.org/2000/svg" => Ok(Namespace::SVG),
"http://www.w3.org/1999/xlink" => Ok(Namespace::XLINK),
"http://www.w3.org/xml/1998/namespace" => Ok(Namespace::XML),
"http://www.w3.org/2000/xmlns/" => Ok(Namespace::XMLNS),
_ => {
bail!("failed to parse namespace of context element")
}
}
}
fn create_element(context_element: Element) -> anyhow::Result<swc_html_ast::Element> {
let mut attributes = Vec::with_capacity(context_element.attributes.len());
for attribute in context_element.attributes.into_iter() {
let namespace = match attribute.namespace {
Some(namespace) => Some(create_namespace(&namespace)?),
_ => None,
};
attributes.push(swc_html_ast::Attribute {
span: DUMMY_SP,
namespace,
prefix: attribute.prefix.map(|value| value.into()),
name: attribute.name.into(),View on GitHub (pinned to 5176682b65)
Solutions
- Normalize namespaces to one of the six exact URIs before calling the API (only 'http://www.w3.org/2000/xmlns/' ends with a slash)
- Omit namespace for un-namespaced elements and attributes
- Filter or map unknown namespaces from context elements produced by upstream parsers
Example fix
// before
contextElement = { tagName: 'svg', namespace: el.namespaceURI };
// el.namespaceURI could be anything DOMParser produced
// after
const KNOWN = new Set([
'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/',
]);
contextElement = {
tagName: 'svg',
namespace: KNOWN.has(el.namespaceURI) ? el.namespaceURI : undefined,
}; Defensive patterns
Strategy: validation
Validate before calling
const KNOWN = new Set([
'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/',
]);
function sanitizeContextElement(el) {
const ns = el.namespace?.toLowerCase();
if (ns && !KNOWN.has(ns)) delete el.namespace;
el.attributes = (el.attributes ?? []).map((a) => {
if (a.namespace && !KNOWN.has(a.namespace.toLowerCase())) {
const { namespace, ...rest } = a;
return rest;
}
return a;
});
return el;
} Type guard
const isKnownNamespace = (ns: string): boolean =>
[
'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/',
].includes(ns.toLowerCase()); Try / catch
try {
const res = await parse(src, { contextElement });
} catch (e) {
if (String(e?.message).includes('namespace of context element')) {
return parse(src, { contextElement: sanitizeContextElement(contextElement) });
}
throw e;
} Prevention
- Sanitize DOMParser-derived context elements before passing them to the wasm binding
- Keep namespace constants in one shared module for both Node and wasm paths
- Add a unit test that feeds each of the six URIs through your context element builder
When it happens
Trigger: Calling the wasm HTML parse API in fragment mode with options.contextElement (or an attribute on it) whose namespace is not one of the six exact URIs, e.g. 'http://www.w3.org/2000/svg/' with a trailing slash or a custom namespace URI.
Common situations: Browser or bundler-integrated tooling reusing context elements parsed by other libraries (DOMParser, parse5) that carry extra namespaces; typos or trailing slashes in hardcoded URIs; assuming the wasm build accepts any namespace because the TS type is string.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to parse namespace of context element
- failed to parse input as document fragment
- failed to parse input as document
- Decl in ExportDecl: {:?}
- failed to parse input as document fragment
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/b0b0b32c4e35cca9.
Report an issue: GitHub.