{"record":{"id":"8a06f50b0ec8a296","repo":"BabylonJS/Babylon.js","slug":"deflate-invalid-huffman-code-lengths","errorCode":null,"errorMessage":"deflate: invalid huffman code lengths","messagePattern":"deflate: invalid huffman code lengths","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/dev/loaders/src/FBX/parsers/zlibInflate.ts","lineNumber":197,"sourceCode":"    }\r\n\r\n    public adler32(): number {\r\n        return ((this.adlerB << 16) | this.adlerA) >>> 0;\r\n    }\r\n}\r\n\r\nclass HuffmanTree {\r\n    private readonly symbolsByLength: Array<Int16Array | undefined>;\r\n    private readonly maxCodeLength: number;\r\n\r\n    public constructor(codeLengths: readonly number[], options: { allowEmpty?: boolean } = {}) {\r\n        const counts = new Array<number>(MAX_BITS + 1).fill(0);\r\n        let nonZeroCount = 0;\r\n        let maxCodeLength = 0;\r\n\r\n        for (const length of codeLengths) {\r\n            if (!Number.isInteger(length) || length < 0 || length > MAX_BITS) {\r\n                throw new Error(\"deflate: invalid huffman code lengths\");\r\n            }\r\n            if (length > 0) {\r\n                counts[length]++;\r\n                nonZeroCount++;\r\n                maxCodeLength = Math.max(maxCodeLength, length);\r\n            }\r\n        }\r\n\r\n        if (nonZeroCount === 0) {\r\n            if (options.allowEmpty) {\r\n                this.symbolsByLength = [];\r\n                this.maxCodeLength = 0;\r\n                return;\r\n            }\r\n            throw new Error(\"deflate: invalid huffman code lengths\");\r\n        }\r\n\r\n        let remaining = 1;\r","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/loaders/src/FBX/parsers/zlibInflate.ts#L179-L215","documentation":"The HuffmanTree constructor validates every code length: each must be an integer between 0 and 15 (DEFLATE's MAX_BITS). A value outside that range (non-integer, negative, or > 15) cannot form a legal Huffman code, so the library throws. Lengths are read as small bit fields from the stream, so this error usually means the bitstream is being decoded from the wrong position or is corrupt.","triggerScenarios":"Constructing a HuffmanTree with code lengths containing NaN, non-integers, negatives, or values > 15 — typically when readCodeLengths decoded symbols from a desynchronized bit position, or code is passed hand-made length arrays with bad values.","commonSituations":"Corrupted FBX payloads; starting the inflate at a wrong offset so dynamic-tree fields decode as garbage; custom code paths constructing HuffmanTree directly with unvalidated arrays; integer overflow when assembling 3-bit length fields from a misaligned reader.","solutions":["Verify the deflate payload starts at the correct offset (immediately after the 2-byte zlib header) so dynamic-tree bit fields are read in position.","Test the same buffer with pako/Node zlib; if that fails too, the file is corrupt and should be re-exported.","If constructing HuffmanTree directly, sanitize lengths first (clamp/validate 0..15, integers only).","Check for recent changes to the parser that altered bit-order or field widths in readDynamicTrees."],"exampleFix":"// before\nconst tree = new HuffmanTree(rawLengths); // rawLengths may contain garbage\n// after\nif (rawLengths.some((l) => !Number.isInteger(l) || l < 0 || l > 15)) {\n    throw new Error(\"malformed compressed payload\");\n}\nconst tree = new HuffmanTree(rawLengths);","handlingStrategy":"validation","validationCode":"function validLengths(lengths: number[]): boolean {\n  return lengths.every((l) => Number.isInteger(l) && l >= 0 && l <= 15);\n}\nif (!validLengths(rawLengths)) throw new Error(\"corrupt code length array\");","typeGuard":"function isValidCodeLength(l: unknown): l is number {\n  return typeof l === \"number\" && Number.isInteger(l) && l >= 0 && l <= 15;\n}","tryCatchPattern":"try {\n  return inflateZlib(payload, count);\n} catch (e) {\n  if (e instanceof Error && e.message === \"deflate: invalid huffman code lengths\") {\n    throw new Error(\"corrupt or misaligned deflate stream — verify payload offset and file integrity\");\n  }\n  throw e;\n}","preventionTips":["Inflate from the exact start of the compressed payload so bit fields align.","Sanitize any lengths you pass to HuffmanTree directly.","Detect file corruption early via checksums on FBX assets.","When a file fails here and also fails in pako, replace the asset rather than patching the parser."],"tags":["deflate","huffman","corrupt-data","validation"],"backgroundTag":"invalid-huffman-code-lengths","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}