BabylonJS/Babylon.js · error

zlib: output length mismatch

Error message

zlib: output length mismatch

What it means

writeByte tried to store a byte past the end of the pre-allocated output Uint8Array sized to expectedLength. The decompressed stream produced more bytes than the caller told inflateZlib to expect (the expected length passed by the FBX array parser). Because the implementation writes exactly expectedLength bytes or fails, any surplus means the declared array length and the actual compressed content disagree.

Source

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

            this.bitCount += 8;
        }
    }
}

class OutputWriter {
    private offset = 0;
    private adlerA = 1;
    private adlerB = 0;

    public readonly bytes: Uint8Array;

    public constructor(expectedLength: number) {
        this.bytes = new Uint8Array(expectedLength);
    }

    public writeByte(value: number): void {
        if (this.offset >= this.bytes.byteLength) {
            throw new Error("zlib: output length mismatch");
        }
        const byte = value & 0xff;
        this.bytes[this.offset++] = byte;
        this.adlerA += byte;
        this.adlerB += this.adlerA;
        this.adlerA %= ADLER_MOD;
        this.adlerB %= ADLER_MOD;
    }

    public copy(distance: number, length: number): void {
        if (distance <= 0 || distance > this.offset) {
            throw new Error("deflate: distance out of range");
        }
        for (let i = 0; i < length; i++) {
            this.writeByte(this.bytes[this.offset - distance]);
        }
    }

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Verify expectedLength comes from the correct FBX node field and matches the element count of the array being decoded.
  2. Check offset/endianness when reading the array length from the binary FBX header.
  3. Re-export the FBX file to regenerate consistent length and payload data.
  4. Log expectedLength versus the offset at failure to see how many extra bytes the stream produced, then fix the source of the count.

Example fix

// before
const count = view.getUint32(nodeOffset + 4, true); // wrong field offset
const arr = inflateZlib(payload, count * 8);
// after
const count = view.getUint32(nodeOffset, true); // correct length field
const arr = inflateZlib(payload, count * 8);
Defensive patterns

Strategy: validation

Validate before calling

// sanity-check declared element count against payload plausibility
if (!Number.isInteger(expectedLength) || expectedLength < 0) throw new Error("bad expectedLength");
if (payload.byteLength < 6) throw new Error("payload too short for declared array");

Try / catch

try {
  return inflateZlib(payload, expectedLength);
} catch (e) {
  if (e instanceof Error && e.message === "zlib: output length mismatch") {
    throw new Error(`decompressed size exceeds declared length ${expectedLength} — check FBX array length field`);
  }
  throw e;
}

Prevention

When it happens

Trigger: inflateZlib(input, expectedLength) is called with an expectedLength smaller than the true decompressed size — e.g. an FBX node whose array length field was read incorrectly (wrong offset, endianness, or stale file version), or a compressed payload that actually decodes to more elements.

Common situations: FBX files edited/re-exported between versions so element counts changed but cached metadata didn't; parsing the wrong node's length field; corruption that flips bits in the length header; copy-paste of array sizes between attribute nodes.

Related errors


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