BabylonJS/Babylon.js · error · Error

Invalid FBX child node end offset ${child.endOffset} at offs

Error message

Invalid FBX child node end offset ${child.endOffset} at offset ${cursor}

What it means

Nested child node records must lie strictly inside their parent: each child's endOffset must be greater than the child's own start cursor and not exceed the parent's endOffset. A child reporting endOffset outside that window indicates a corrupt record or a header-layout (32/64-bit) mismatch during recursive parsing.

Source

Thrown at packages/dev/loaders/src/FBX/parsers/fbxBinaryParser.ts:109

    for (let i = 0; i < numProperties; i++) {
        const result = parseProperty(view, bytes, cursor, propertiesEnd);
        properties.push(result.property);
        cursor = result.nextOffset;
    }
    if (cursor !== propertiesEnd) {
        throw new Error(`Invalid FBX property list length for node '${name}' at offset ${offset}`);
    }

    // Parse nested child nodes (between end of properties and endOffset)
    const children: FBXNode[] = [];
    if (cursor < endOffset) {
        while (cursor < endOffset) {
            const child = parseNode(view, bytes, cursor, is64Bit, endOffset);
            if (child === null) {
                break;
            }
            if (child.endOffset <= cursor || child.endOffset > endOffset) {
                throw new Error(`Invalid FBX child node end offset ${child.endOffset} at offset ${cursor}`);
            }
            children.push(child.node);
            cursor = child.endOffset;
        }
    }

    return {
        node: { name, properties, children },
        endOffset,
    };
}

interface ParsedProperty {
    property: FBXProperty;
    nextOffset: number;
}

function parseProperty(view: DataView, bytes: Uint8Array, offset: number, limit: number): ParsedProperty {

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Confirm the version field at byte offset 23 matches the actual FBX version so the correct (32/64-bit) header size is used
  2. Re-download/re-export the file to eliminate corruption
  3. Validate against the FBX binary spec by hexdumping the child record header at `cursor`
  4. Add a pre-parse guard that rejects files whose version field is implausible (0 or > 10000)
Defensive patterns

Strategy: try-catch

Validate before calling

const version = new DataView(buffer).getUint32(23, true);
if (!(version >= 6000 && version <= 10000)) throw new Error("Implausible FBX version — likely wrong/corrupt file");
// ensure 64-bit layout is applied for >= 7500 (parser does this; the check catches corrupt version fields)

Type guard

function fbxLayoutOk(buf) {
  if (buf.byteLength < 27) return false;
  const v = new DataView(buf).getUint32(23, true);
  return v >= 6000 && v <= 10000;
}

Try / catch

try {
  const doc = parseBinaryFBX(buffer);
} catch (e) {
  if (/Invalid FBX child node end offset/.test(e.message)) {
    console.error("Nested FBX node out of parent bounds — corrupt record or header-layout mismatch; re-export the FBX");
  } else throw e;
}

Prevention

When it happens

Trigger: The child-parsing loop in parseNode (via `result`/`child`) reads a nested node whose decoded endOffset is <= cursor or > parent endOffset — typically corruption, or a 64-bit-offset file parsed with the 32-bit reader when the version check at byte 23 failed.

Common situations: FBX 7.5+ files with unusual version fields; corrupted transfers; files stitched/merged incorrectly; fuzzed inputs.

Related errors


AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30). Data as JSON: /api/errors/f8bf09a4e847b32f. Report an issue: GitHub.