BabylonJS/Babylon.js · error

deflate: invalid literal/length symbol

Error message

deflate: invalid literal/length symbol

What it means

In deflate, literal/length symbols are valid in 0-285; symbols 286 and 287 exist in the fixed table's 288-symbol space but are illegal. This error is thrown when the Huffman decoder returns a symbol >285, meaning the bitstream encoded an invalid code — a strong sign the data does not match the tree or is corrupt.

Source

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

    }

    for (let i = 0; i < length; i++) {
        output.writeByte(reader.readByte());
    }
}

function inflateCompressedBlock(reader: BitReader, output: OutputWriter, literalLengthTree: HuffmanTree, distanceTree: HuffmanTree): void {
    while (true) {
        const symbol = literalLengthTree.decode(reader);
        if (symbol < 256) {
            output.writeByte(symbol);
            continue;
        }
        if (symbol === 256) {
            return;
        }
        if (symbol > 285) {
            throw new Error("deflate: invalid literal/length symbol");
        }

        const lengthIndex = symbol - 257;
        const length = LENGTH_BASE[lengthIndex] + reader.readBits(LENGTH_EXTRA_BITS[lengthIndex]);
        const distanceSymbol = distanceTree.decode(reader);
        if (distanceSymbol > 29) {
            throw new Error("deflate: invalid distance symbol");
        }
        const distance = DISTANCE_BASE[distanceSymbol] + reader.readBits(DISTANCE_EXTRA_BITS[distanceSymbol]);
        output.copy(distance, length);
    }
}

function readDynamicTrees(reader: BitReader): {
    literalLengthTree: HuffmanTree;
    distanceTree: HuffmanTree;
} {
    const literalLengthCount = reader.readBits(5) + 257;

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Validate the payload independently with python zlib.decompress to isolate data corruption vs parsing bugs
  2. Ensure the FBX array's 'Encoding' field is 1 (zlib) before calling inflateZlib — Encoding 0 data is uncompressed and will decode as garbage
  3. Re-export the FBX from the DCC tool
  4. Check the offset used to slice the payload matches the reader position after the property header

Example fix

// before: inflating regardless of encoding flag
const out = inflateZlib(payload, expectedLen);
// after
const out = encoding === 1 ? inflateZlib(payload, expectedLen) : payload;
Defensive patterns

Strategy: validation

Validate before calling

if (fbxArray.encoding !== 1) {
  throw new Error(`Unexpected FBX array encoding ${fbxArray.encoding}; expected 1 (zlib)`);
}
if (payload.byteLength < 6) throw new Error("Payload too short to be zlib");

Type guard

function isCompressedArray(p: { encoding: number; payload: Uint8Array }): boolean {
  return p.encoding === 1 && p.payload.byteLength >= 6;
}

Try / catch

try {
  const arr = inflateZlib(payload, expectedLength);
} catch (e) {
  if (e instanceof Error && e.message === "deflate: invalid literal/length symbol") {
    throw new Error("Corrupt FBX compressed array (invalid deflate symbol)", { cause: e });
  }
  throw e;
}

Prevention

When it happens

Trigger: inflateCompressedBlock, while decoding a type-1 (fixed) or type-2 (dynamic) block for an FBX compressed array, gets symbol 286/287 from literalLengthTree.decode(reader) — corrupt bits, or fixed-block decoding applied to data that isn't fixed-Huffman deflate.

Common situations: Payload that is gzip (header differs, but if someone strips wrappers manually) or otherwise not the format expected; truncated streams decoding leftover padding bits as codes; hand-crafted or tool-broken FBX files.

Related errors


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