BabylonJS/Babylon.js · error
deflate: invalid huffman code lengths
Error message
deflate: invalid huffman code lengths
What it means
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.
Source
Thrown at packages/dev/loaders/src/FBX/parsers/zlibInflate.ts:197
}
public adler32(): number {
return ((this.adlerB << 16) | this.adlerA) >>> 0;
}
}
class HuffmanTree {
private readonly symbolsByLength: Array<Int16Array | undefined>;
private readonly maxCodeLength: number;
public constructor(codeLengths: readonly number[], options: { allowEmpty?: boolean } = {}) {
const counts = new Array<number>(MAX_BITS + 1).fill(0);
let nonZeroCount = 0;
let maxCodeLength = 0;
for (const length of codeLengths) {
if (!Number.isInteger(length) || length < 0 || length > MAX_BITS) {
throw new Error("deflate: invalid huffman code lengths");
}
if (length > 0) {
counts[length]++;
nonZeroCount++;
maxCodeLength = Math.max(maxCodeLength, length);
}
}
if (nonZeroCount === 0) {
if (options.allowEmpty) {
this.symbolsByLength = [];
this.maxCodeLength = 0;
return;
}
throw new Error("deflate: invalid huffman code lengths");
}
let remaining = 1;
View on GitHub (pinned to 0592b347b8)
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.
Example fix
// before
const tree = new HuffmanTree(rawLengths); // rawLengths may contain garbage
// after
if (rawLengths.some((l) => !Number.isInteger(l) || l < 0 || l > 15)) {
throw new Error("malformed compressed payload");
}
const tree = new HuffmanTree(rawLengths); Defensive patterns
Strategy: validation
Validate before calling
function validLengths(lengths: number[]): boolean {
return lengths.every((l) => Number.isInteger(l) && l >= 0 && l <= 15);
}
if (!validLengths(rawLengths)) throw new Error("corrupt code length array"); Type guard
function isValidCodeLength(l: unknown): l is number {
return typeof l === "number" && Number.isInteger(l) && l >= 0 && l <= 15;
} Try / catch
try {
return inflateZlib(payload, count);
} catch (e) {
if (e instanceof Error && e.message === "deflate: invalid huffman code lengths") {
throw new Error("corrupt or misaligned deflate stream — verify payload offset and file integrity");
}
throw e;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- deflate: invalid huffman code
- deflate: invalid literal/length symbol
- deflate: invalid distance symbol
- deflate: invalid block type
- deflate: expected byte alignment
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/8a06f50b0ec8a296.
Report an issue: GitHub.