{"record":{"id":"f6b8447e4afc3950","repo":"BabylonJS/Babylon.js","slug":"truncated-binary-fbx-header","errorCode":null,"errorMessage":"Truncated binary FBX header","messagePattern":"Truncated binary FBX header","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/dev/loaders/src/FBX/parsers/fbxBinaryParser.ts","lineNumber":22,"sourceCode":"\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\n        offset = result.endOffset;\r\n    }\r\n\r","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/loaders/src/FBX/parsers/fbxBinaryParser.ts#L4-L40","documentation":"A binary FBX file must contain at least a 27-byte header (21-byte magic, 2 padding bytes, 4-byte version uint32). If the ArrayBuffer is shorter than HEADER_SIZE the file is truncated and no version or node data can be read, so the parser throws.","triggerScenarios":"Calling the binary FBX parse (via `_parseFromArrayBuffer`/`doc`) with an ArrayBuffer of byteLength < 27 — e.g. an empty buffer, a partially downloaded file, or a tiny placeholder file.","commonSituations":"Incomplete uploads/downloads; file reads aborted mid-way producing zero-length buffers; test fixtures containing stub files; streaming code that passes a partial chunk instead of the whole file.","solutions":["Check `buffer.byteLength >= 27` before parsing; re-fetch the file if shorter","Re-download/re-upload the asset — the file on disk may itself be truncated","Ensure the whole file is read into the buffer (await full read, use Blob.arrayBuffer()/fs full read)","If handling untrusted input, treat this as invalid input and surface a user-facing 'corrupt file' message"],"exampleFix":"// before\nparseBinaryFBX(await partialChunk.arrayBuffer());\n// after\nconst buf = await file.arrayBuffer();\nif (buf.byteLength < 27) throw new Error(\"FBX file is truncated\");\nparseBinaryFBX(buf);","handlingStrategy":"validation","validationCode":"function hasFbxHeader(buf) {\n  return buf instanceof ArrayBuffer && buf.byteLength >= 27;\n}\nif (!hasFbxHeader(buffer)) throw new Error(\"FBX buffer too small/truncated\");","typeGuard":"function isPlausibleFbxBuffer(buf) {\n  return buf instanceof ArrayBuffer && buf.byteLength >= 27;\n}","tryCatchPattern":"try {\n  const doc = parseBinaryFBX(buffer);\n} catch (e) {\n  if (e.message === \"Truncated binary FBX header\") {\n    console.error(`Buffer is ${buffer.byteLength} bytes; need ≥27 — re-fetch the file`);\n  } else throw e;\n}","preventionTips":["Always check byteLength before creating a DataView","Await full reads (Blob.arrayBuffer, complete fs reads) — never pass stream chunks","Verify downloaded size against Content-Length or expected size","Guard test fixtures against empty/placeholder files"],"tags":["fbx","binary","truncated","header","corrupt-file"],"backgroundTag":"truncated-file","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}