BabylonJS/Babylon.js · error

deflate: missing end-of-block code

Error message

deflate: missing end-of-block code

What it means

RFC 1951 requires every dynamic block's literal/length alphabet to define a nonzero code length for symbol 256 (end-of-block). This error is thrown in readDynamicTrees when the decoded lengths for the literal/length table assign zero length to symbol 256, so the block could never terminate — the header data is corrupt or was not produced by a compliant compressor.

Source

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

    literalLengthTree: HuffmanTree;
    distanceTree: HuffmanTree;
} {
    const literalLengthCount = reader.readBits(5) + 257;
    const distanceCount = reader.readBits(5) + 1;
    const codeLengthCount = reader.readBits(4) + 4;

    const codeLengthLengths = new Array<number>(19).fill(0);
    for (let i = 0; i < codeLengthCount; i++) {
        codeLengthLengths[CODE_LENGTH_ORDER[i]] = reader.readBits(3);
    }

    const codeLengthTree = new HuffmanTree(codeLengthLengths);
    const lengths = readCodeLengths(reader, codeLengthTree, literalLengthCount + distanceCount);
    const literalLengthLengths = lengths.slice(0, literalLengthCount);
    const distanceLengths = lengths.slice(literalLengthCount);

    if (literalLengthLengths[256] === 0) {
        throw new Error("deflate: missing end-of-block code");
    }

    return {
        literalLengthTree: new HuffmanTree(literalLengthLengths),
        distanceTree: new HuffmanTree(distanceLengths, { allowEmpty: true }),
    };
}

function readCodeLengths(reader: BitReader, codeLengthTree: HuffmanTree, count: number): number[] {
    const lengths: number[] = [];
    while (lengths.length < count) {
        const symbol = codeLengthTree.decode(reader);
        if (symbol <= 15) {
            lengths.push(symbol);
            continue;
        }

        let repeatLength: number;

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Validate the payload with python zlib.decompress to confirm the data is bad vs the loader offsets being wrong
  2. Check the FBX array header's compressed byte count and that the slice passed to inflateZlib starts at the zlib CMF byte
  3. Re-export the asset from the source DCC tool
  4. If many files from one pipeline fail, audit that pipeline's compression step
Defensive patterns

Strategy: validation

Validate before calling

// Independent pre-validation of the payload
import { decompressSync } from "fflate"; // or any zlib impl
try { decompressSync(payload); } catch { throw new Error("FBX payload fails reference zlib decode — file corrupt"); }

Try / catch

try {
  const out = inflateZlib(payload, expectedLength);
} catch (e) {
  if (e instanceof Error && e.message === "deflate: missing end-of-block code") {
    throw new Error("FBX dynamic block lacks end-of-block symbol — corrupt stream", { cause: e });
  }
  throw e;
}

Prevention

When it happens

Trigger: inflateZlib reads a type-2 dynamic block; readCodeLengths decodes HLIT+HDIST code lengths, and lengths.slice(0, literalLengthCount)[256] === 0, i.e. the end-of-block symbol has no code.

Common situations: Corrupt or truncated FBX compressed arrays (header bytes of the block lost); misaligned payload slicing reading garbage into the dynamic header; files produced by broken experimental compressors.

Related errors


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