BabylonJS/Babylon.js · error

deflate: invalid huffman code

Error message

deflate: invalid huffman code

What it means

HuffmanTree.decode throws immediately when the tree was built with maxCodeLength === 0, i.e. the tree has no symbols at all. For a distance tree this is allowed at build time (allowEmpty) but becomes fatal the moment the stream actually tries to decode a distance code from it, indicating the compressed stream references back-references while defining an empty distance alphabet.

Source

Thrown at packages/dev/loaders/src/FBX/parsers/zlibInflate.ts:253

                return undefined;
            }
            const symbols = new Int16Array(1 << length);
            symbols.fill(-1);
            return symbols;
        });
        for (let symbol = 0; symbol < codeLengths.length; symbol++) {
            const length = codeLengths[symbol];
            if (length === 0) {
                continue;
            }
            this.symbolsByLength[length]![nextCode[length]++] = symbol;
        }
        this.maxCodeLength = maxCodeLength;
    }

    public decode(reader: BitReader): number {
        if (this.maxCodeLength === 0) {
            throw new Error("deflate: invalid huffman code");
        }

        let code = 0;
        for (let length = 1; length <= this.maxCodeLength; length++) {
            code = (code << 1) | reader.readBit();
            const symbol = this.symbolsByLength[length]?.[code] ?? -1;
            if (symbol >= 0) {
                return symbol;
            }
        }
        throw new Error("deflate: invalid huffman code");
    }
}

let fixedLiteralLengthTree: HuffmanTree | undefined;
let fixedDistanceTree: HuffmanTree | undefined;

function getFixedLiteralLengthTree(): HuffmanTree {

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Extract the array payload and test it with python's zlib.decompress to confirm whether the payload itself is valid deflate data
  2. Verify the FBX array property header (encoding flag and compressed byte count) matches how the payload is sliced before inflateZlib
  3. Re-export the asset from the DCC tool; an empty distance tree with a length symbol is never produced by compliant compressors
  4. If this happens on previously-working files, check whether the loader version changed how payload offsets are computed
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure encoding flag is zlib before inflating
if (fbxArray.encoding !== 1) throw new Error("Array is not zlib-compressed");

Type guard

function isZlibEncoded(enc: number): enc is 1 {
  return enc === 1;
}

Try / catch

try {
  const arr = parseArrayProperty(...);
} catch (e) {
  if (e instanceof Error && e.message === "deflate: invalid huffman code") {
    console.error("FBX compressed array references distances with an empty distance tree — file is corrupt");
  }
  throw e;
}

Prevention

When it happens

Trigger: inflateCompressedBlock decodes a length symbol (257-285) and calls distanceTree.decode(reader), but the dynamic distance tree built from the block header was empty (all distance code lengths zero) — a stream that promises lengths but supplies no distance codes.

Common situations: Corrupt or non-standard FBX compressed arrays; a compressor bug emitting a length symbol without any distance tree; reading data from the wrong offset so garbage bits form a length symbol.

Related errors


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