BabylonJS/Babylon.js · error
att() without open element
Error message
att() without open element
What it means
XmlBuilder.att() writes an XML attribute, which is only legal while an element's start tag is open. The builder keeps a stack of open element contexts via _peekContext(); when the stack is empty (no open element), there is nowhere to attach the attribute, so it throws this error. This enforces correct XML structure at builder time.
Source
Thrown at packages/dev/serializers/src/3MF/core/xml/xml.builder.ts:135
}
if (standalone !== undefined) {
this._writeAttStr(XmlSyntax.StandaloneKeyword, standalone ? "yes" : "no");
}
this._w.write(XmlSyntax.Question, XmlSyntax.CloseTag);
return this;
}
/**
*
* @param ns
* @param n
* @param v
* @returns
*/
public att(ns: string | null, n: string, v: string): IXmlBuilder {
const ctx = this._peekContext();
if (!ctx) {
throw new Error("att() without open element");
}
if (ctx.closed) {
throw new Error(`att() after start tag closed for <${ctx.name}>`);
}
// explicit namespace declaration: xmlns or xmlns:prefix
if (this._isXmlnsDecl(ns, n)) {
if (n === XmlSyntax.Xmlns) {
// default namespace
ctx.defaultNs = v;
// you can store default as empty prefix if you want
this._registerNamespace(ctx, "", v);
this._writeAttStr(XmlSyntax.Xmlns, v);
} else {
if (!ns) {
const prefix = n.slice(6); // "xmlns:"
this._registerNamespace(ctx, prefix, v);
this._writeAttStr(n, v);
View on GitHub (pinned to 0592b347b8)
Solutions
- Call the element/open method before att(), and attach attributes before adding children or closing the element.
- Reorder builder calls so each att() follows its element() open call.
- Check for unbalanced close/at calls earlier in the builder chain that closed the element prematurely.
- Inspect _peekContext/state: ensure the element stack is non-empty at the att() call site.
Example fix
// before
const b = new XmlBuilder();
b.att(null, "id", "1"); // throws
// after
const b = new XmlBuilder();
b.el("model", null, null).att(null, "id", "1"); Defensive patterns
Strategy: try-catch
Try / catch
try {
b.att(ns, name, value);
} catch (e) {
if (e instanceof Error && e.message === 'att() without open element') {
b.el('root').att(ns, name, value); // recover by opening the element first
} else throw e;
} Prevention
- Always open an element before writing attributes.
- Order builder calls strictly: el -> att* -> text/children -> close.
- Keep a helper that opens the root element first in every serialize function.
- Validate builder call order in unit tests.
When it happens
Trigger: Calling att() before any element()/openElement call, or after the root element was fully closed, or after an unbalanced at()el()/close sequence emptied the element stack.
Common situations: Misordered builder calls (attributes emitted before the element); writing document-level content outside a root element; exception paths that closed elements early then continued adding attributes.
Related errors
- text() without open element
- att() after start tag closed for <${ctx.name}>
- Atmosphere only supports one light source currently.
- Multi-file loading not allowed on env files.
- WebGPUComputeContext.getBindGroups: bindingsMapping is requi
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/442f8139b394b287.
Report an issue: GitHub.