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
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.
Source
Thrown at bindings/binding_html_node/src/lib.rs:234
Ok(output)
}
}
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
- 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
Example fix
// before
const res = parseSync(src, {
contextElement: {
tagName: 'svg',
namespace: 'http://www.w3.org/2000/svg/', // trailing slash -> bail
},
});
// after
const res = parseSync(src, {
contextElement: {
tagName: 'svg',
namespace: 'http://www.w3.org/2000/svg',
},
}); Defensive patterns
Strategy: validation
Validate before calling
const KNOWN_NAMESPACES = 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 normalizeNamespace(ns) {
if (ns == null) return undefined;
const lower = ns.toLowerCase();
if (!KNOWN_NAMESPACES.has(lower)) {
throw new RangeError(`unsupported namespace: ${ns}`);
}
return lower;
}
contextElement.namespace = normalizeNamespace(contextElement.namespace); Type guard
const isKnownNamespace = (ns: string): boolean =>
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/',
]).has(ns.toLowerCase()); Try / catch
try {
const res = parseSync(src, { contextElement });
} catch (e) {
if (String(e?.message).includes('namespace of context element')) {
return parseSync(src, { contextElement: stripNamespaces(contextElement) });
}
throw e;
} Prevention
- 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
When it happens
Trigger: 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'.
Common situations: 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.
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
- Invalid attempt to iterate non-iterable instance. In order t
- Duplicated methods (${element.key}) can't be decorated.
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/8a39307c7333c398.
Report an issue: GitHub.