{"record":{"id":"1b69fb60d2ef8726","repo":"BabylonJS/Babylon.js","slug":"not-a-valid-binary-fbx-file","errorCode":null,"errorMessage":"Not a valid binary FBX file","messagePattern":"Not a valid binary FBX file","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/dev/loaders/src/FBX/parsers/fbxBinaryParser.ts","lineNumber":19,"sourceCode":"/* eslint-disable @typescript-eslint/naming-convention, jsdoc/require-param, jsdoc/require-returns */\r\nimport { type FBXDocument, type FBXNode, type FBXProperty, type FBXPropertyType } from \"../types/fbxTypes\";\r\nimport { inflateZlib } from \"./zlibInflate\";\r\n\r\nconst FBX_MAGIC = \"Kaydara FBX Binary  \\0\";\r\nconst HEADER_SIZE = 27; // 21 magic + 2 padding + 4 version uint32\r\n\r\n/**\r\n * Parse a binary FBX file into an FBXDocument.\r\n * Supports FBX versions 7.0–7.7 (v7.5+ uses 64-bit node headers).\r\n */\r\nexport function parseBinaryFBX(buffer: ArrayBuffer): FBXDocument {\r\n    const view = new DataView(buffer);\r\n    const bytes = new Uint8Array(buffer);\r\n\r\n    // Validate magic\r\n    const magic = decodeASCII(bytes, 0, 21);\r\n    if (magic !== FBX_MAGIC) {\r\n        throw new Error(\"Not a valid binary FBX file\");\r\n    }\r\n    if (buffer.byteLength < HEADER_SIZE) {\r\n        throw new Error(\"Truncated binary FBX header\");\r\n    }\r\n\r\n    const version = view.getUint32(23, true);\r\n    // v7.5+ uses 64-bit offsets in node records\r\n    const is64Bit = version >= 7500;\r\n\r\n    const nodes: FBXNode[] = [];\r\n    let offset = HEADER_SIZE;\r\n\r\n    while (offset < buffer.byteLength) {\r\n        const result = parseNode(view, bytes, offset, is64Bit, buffer.byteLength);\r\n        if (result === null) {\r\n            break; // null sentinel node\r\n        }\r\n        nodes.push(result.node);\r","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/loaders/src/FBX/parsers/fbxBinaryParser.ts#L1-L37","documentation":"parseBinaryFBX validates the file begins with the exact 21-byte magic string `Kaydara FBX Binary  \\0`. If the first bytes differ, the input is not a binary FBX file, and parsing cannot proceed — the parser throws immediately before reading the header/version.","triggerScenarios":"Calling the loader's ArrayBuffer parse path (via `_parseFromArrayBuffer`/`doc`) with bytes that are ASCII FBX, a ZIP archive (often mistakenly called .fbx), an OBJ/DAE file, or any non-FBX binary.","commonSituations":"Feeding ASCII FBX into the binary parser (or vice versa); renaming a .zip (FBX 2020+ default is actually binary but some pipelines store zipped FBX) or .dae to .fbx; corrupted uploads where the magic bytes are lost.","solutions":["Check the first bytes of the file — if it starts with `Kaydara FBX Binary` it is binary; if it starts with text like `; FBX` use the ASCII parser","If the file starts with `PK`, it is a ZIP — unzip it to get the real FBX","Re-export the asset as FBX binary from the DCC tool","Verify the file was not truncated/transformed in transit (e.g. text-mode transfer corrupting bytes)"],"exampleFix":"// before\nloader.parse(fbxBytes); // bytes are actually ASCII FBX\n// after\nconst isBinary = new TextDecoder().decode(bytes.slice(0, 21)) === \"Kaydara FBX Binary  \";\nif (isBinary) loader.parse(bytes); else loader.parse(text);","handlingStrategy":"validation","validationCode":"const MAGIC = \"Kaydara FBX Binary  \\0\";\nfunction isBinaryFbx(buf) {\n  if (buf.byteLength < 27) return false;\n  let s = \"\";\n  const b = new Uint8Array(buf, 0, 21);\n  for (const x of b) s += String.fromCharCode(x);\n  return s === MAGIC;\n}\nif (!isBinaryFbx(buffer)) throw new Error(\"Not binary FBX — use the ASCII parser or convert the file\");","typeGuard":"function isBinaryFbxBuffer(buf) {\n  if (!(buf instanceof ArrayBuffer) || buf.byteLength < 27) return false;\n  const magic = String.fromCharCode(...new Uint8Array(buf, 0, 21));\n  return magic === \"Kaydara FBX Binary  \\0\";\n}","tryCatchPattern":"try {\n  const doc = parseBinaryFBX(buffer);\n} catch (e) {\n  if (e.message === \"Not a valid binary FBX file\") {\n    // sniff: PK => zip, '<' or '; FBX' => ascii/xml; route accordingly\n    console.error(\"Wrong format fed to binary FBX parser\");\n  } else throw e;\n}","preventionTips":["Route files by sniffing the 21-byte magic before selecting ASCII vs binary parser","Watch for PK zip signatures — some '.fbx' payloads are zips","Keep magic/HEADERSIZE checks before any DataView reads","Validate uploads at ingest with the same magic check"],"tags":["fbx","binary","magic-bytes","wrong-format","validation"],"backgroundTag":"invalid-file-format-magic","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}