BabylonJS/Babylon.js · error
reserved prefix '${prefix}'
Error message
reserved prefix '${prefix}' What it means
XmlBuilder._registerNamespace() rejects attempts to bind the XML-reserved prefixes 'xml' and 'xmlns' to custom namespaces, per the XML Namespaces spec where these prefixes are predefined and immutable. Registering them would produce invalid namespace declarations, so the builder throws immediately.
Source
Thrown at packages/dev/serializers/src/3MF/core/xml/xml.builder.ts:289
private _escAttr(s: string): string {
return this._escText(s).replace(/"/g, """).replace(/'/g, "'");
}
private _isXmlnsDecl(ns: string | null, n: string): boolean {
if (ns) {
return ns === XmlSyntax.Xmlns;
}
const l = n.length;
const s = XmlSyntax.Xmlns.length;
if (l >= s) {
return n.startsWith(XmlSyntax.Xmlns) && (n.length == s || n[s] == XmlSyntax.Semicolon);
}
return false;
}
private _registerNamespace(ctx: InstanceType<typeof XmlBuilder.Context>, prefix: string, uri: string) {
if (prefix === XmlSyntax.Xml || prefix === XmlSyntax.Xmlns) {
throw new Error(`reserved prefix '${prefix}'`);
}
const existingUri = ctx.prefix2ns.get(prefix);
if (existingUri && existingUri !== uri) {
throw new Error(`prefix '${prefix}' already bound to a different namespace`);
}
const existingPrefix = ctx.ns2prefix.get(uri);
if (!existingPrefix) {
ctx.ns2prefix.set(uri, prefix);
}
ctx.prefix2ns.set(prefix, uri);
}
private _allocPrefix(ctx: InstanceType<typeof XmlBuilder.Context>): string {
let i = 1;
while (true) {
View on GitHub (pinned to 0592b347b8)
Solutions
- Use a non-reserved prefix (anything other than 'xml'/'xmlns') for your namespace URI.
- Validate/sanitize user- or config-supplied prefixes before passing them to the builder.
- Fix prefix-generation logic to exclude reserved names from candidates.
- If you need the standard xml namespace, rely on the implicit predefined binding instead of declaring it.
Example fix
// before
b.att("xmlns", "xml", "http://my.namespace"); // throws
// after
b.att("http://my.namespace", "myattr", "value"); // builder declares e.g. xmlns:ns0=... Defensive patterns
Strategy: validation
Validate before calling
const RESERVED = ['xml', 'xmlns'];
function assertSafePrefix(prefix: string): void {
if (RESERVED.includes(prefix)) throw new Error(`prefix '${prefix}' is reserved`);
}
assertSafePrefix(myPrefix); Type guard
function isSafePrefix(p: string): boolean {
return p !== 'xml' && p !== 'xmlns' && /^[A-Za-z_][\w.-]*$/.test(p);
} Try / catch
try {
b.att(ns, n, v);
} catch (e) {
if (e instanceof Error && e.message.startsWith('reserved prefix')) {
// swap in a generated non-reserved prefix and retry
} else throw e;
} Prevention
- Never declare namespaces with prefix 'xml' or 'xmlns'.
- Sanitize user/config-supplied prefixes before use.
- Make prefix generators exclude reserved names.
- Rely on the implicit xml namespace instead of re-declaring it.
When it happens
Trigger: Calling att() with ns/name forming an xmlns:xml or xmlns:xmlns declaration, or _ensurePrefixDeclared() choosing/resolving the reserved prefix for a namespace URI mapping.
Common situations: Hardcoding prefix 'xml' for a custom namespace by mistake; a prefix generator/collision resolver that can pick 'xml' or 'xmlns'; copying a namespace map that includes reserved prefixes; user-supplied prefix configuration without validation.
Related errors
- Sample2DRgbaToRef: widthPx and heightPx must be positive.
- At least one mesh is needed to create the nav mesh.
- At least one mesh is needed to create the nav mesh.
- Unable to create navmesh. No navMesh or navMeshQuery returne
- step size should be less than 1.
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/88af11e64a753c18.
Report an issue: GitHub.