{"record":{"id":"88af11e64a753c18","repo":"BabylonJS/Babylon.js","slug":"reserved-prefix-prefix","errorCode":null,"errorMessage":"reserved prefix '${prefix}'","messagePattern":"reserved prefix '(.+?)'","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/dev/serializers/src/3MF/core/xml/xml.builder.ts","lineNumber":289,"sourceCode":"    private _escAttr(s: string): string {\r\n        return this._escText(s).replace(/\"/g, \"&quot;\").replace(/'/g, \"&apos;\");\r\n    }\r\n\r\n    private _isXmlnsDecl(ns: string | null, n: string): boolean {\r\n        if (ns) {\r\n            return ns === XmlSyntax.Xmlns;\r\n        }\r\n        const l = n.length;\r\n        const s = XmlSyntax.Xmlns.length;\r\n        if (l >= s) {\r\n            return n.startsWith(XmlSyntax.Xmlns) && (n.length == s || n[s] == XmlSyntax.Semicolon);\r\n        }\r\n        return false;\r\n    }\r\n\r\n    private _registerNamespace(ctx: InstanceType<typeof XmlBuilder.Context>, prefix: string, uri: string) {\r\n        if (prefix === XmlSyntax.Xml || prefix === XmlSyntax.Xmlns) {\r\n            throw new Error(`reserved prefix '${prefix}'`);\r\n        }\r\n\r\n        const existingUri = ctx.prefix2ns.get(prefix);\r\n        if (existingUri && existingUri !== uri) {\r\n            throw new Error(`prefix '${prefix}' already bound to a different namespace`);\r\n        }\r\n\r\n        const existingPrefix = ctx.ns2prefix.get(uri);\r\n        if (!existingPrefix) {\r\n            ctx.ns2prefix.set(uri, prefix);\r\n        }\r\n\r\n        ctx.prefix2ns.set(prefix, uri);\r\n    }\r\n\r\n    private _allocPrefix(ctx: InstanceType<typeof XmlBuilder.Context>): string {\r\n        let i = 1;\r\n        while (true) {\r","sourceCodeStart":271,"sourceCodeEnd":307,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/serializers/src/3MF/core/xml/xml.builder.ts#L271-L307","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nb.att(\"xmlns\", \"xml\", \"http://my.namespace\"); // throws\n// after\nb.att(\"http://my.namespace\", \"myattr\", \"value\"); // builder declares e.g. xmlns:ns0=...","handlingStrategy":"validation","validationCode":"const RESERVED = ['xml', 'xmlns'];\nfunction assertSafePrefix(prefix: string): void {\n    if (RESERVED.includes(prefix)) throw new Error(`prefix '${prefix}' is reserved`);\n}\nassertSafePrefix(myPrefix);","typeGuard":"function isSafePrefix(p: string): boolean {\n    return p !== 'xml' && p !== 'xmlns' && /^[A-Za-z_][\\w.-]*$/.test(p);\n}","tryCatchPattern":"try {\n    b.att(ns, n, v);\n} catch (e) {\n    if (e instanceof Error && e.message.startsWith('reserved prefix')) {\n        // swap in a generated non-reserved prefix and retry\n    } else throw e;\n}","preventionTips":["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."],"tags":["xml","namespace","reserved-word","validation"],"backgroundTag":"reserved-xml-prefix","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}