BabylonJS/Babylon.js · error
zlib: invalid expected length
Error message
zlib: invalid expected length
What it means
inflateZlib validates its expectedLength argument before inflating and throws 'zlib: invalid expected length' if it is not a non-negative integer. This guards the pre-allocated output buffer, which must have an exact known size for one-shot FBX array decompression.
Source
Thrown at packages/dev/loaders/src/FBX/parsers/zlibInflate.ts:19
/* eslint-disable @typescript-eslint/naming-convention, jsdoc/require-param, jsdoc/require-returns */
const ADLER_MOD = 65521;
const MAX_BITS = 15;
const LENGTH_BASE = [3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258];
const LENGTH_EXTRA_BITS = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0];
const DISTANCE_BASE = [1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577];
const DISTANCE_EXTRA_BITS = [0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13];
const CODE_LENGTH_ORDER = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15];
/**
* Inflate a zlib-wrapped deflate stream.
*
* This implementation is intentionally scoped to FBX binary array payloads: one-shot,
* synchronous zlib streams with the exact uncompressed length known up front.
*/
export function inflateZlib(input: Uint8Array, expectedLength: number): Uint8Array {
if (!Number.isInteger(expectedLength) || expectedLength < 0) {
throw new Error("zlib: invalid expected length");
}
if (input.byteLength < 6) {
throw new Error("zlib: unexpected end of input");
}
const cmf = input[0];
const flg = input[1];
if ((cmf & 0x0f) !== 8 || cmf >> 4 > 7 || ((cmf << 8) + flg) % 31 !== 0) {
throw new Error("zlib: invalid header");
}
if ((flg & 0x20) !== 0) {
throw new Error("zlib: preset dictionary not supported");
}
const reader = new BitReader(input, 2, input.byteLength - 4);
const output = new OutputWriter(expectedLength);
let isFinalBlock = false;
View on GitHub (pinned to 0592b347b8)
Solutions
- Fix the element-count/element-size computation in parseArrayProperty so expectedByteLength is a non-negative integer
- Sanity-check the FBX record's array count field — a huge or negative count means a corrupt file
- If calling inflateZlib yourself, validate the length first (Number.isInteger(n) && n >= 0)
- Re-export the source FBX file if the count field is corrupt
Example fix
// before
return inflateZlib(compressed, count * size); // NaN if size unknown
// after
const expected = count * size;
if (!Number.isInteger(expected) || expected < 0) throw new Error(`Bad array length for ${type}`);
return inflateZlib(compressed, expected); Defensive patterns
Strategy: validation
Validate before calling
const expected = count * ELEMENT_SIZES[type];
if (!Number.isInteger(expected) || expected < 0) {
throw new Error(`Corrupt FBX array length for ${type}: ${expected}`);
}
return inflateZlib(compressed, expected); Type guard
function isValidInflateLength(n: unknown): n is number {
return typeof n === 'number' && Number.isInteger(n) && n >= 0;
} Try / catch
try {
return inflateZlib(input, expectedLength);
} catch (e) {
if ((e as Error).message === 'zlib: invalid expected length') {
throw new Error('FBX array record has corrupt element count', { cause: e });
}
throw e;
} Prevention
- Validate the length argument before calling inflateZlib
- Sanity-check FBX array count fields against a reasonable maximum
- Add unit tests for degenerate counts (0, negative, huge)
When it happens
Trigger: parseArrayProperty computing expectedByteLength as NaN/undefined (e.g., unknown element size multiplied by count), a negative product from a corrupt count field, or a non-integer from a fractional size calculation.
Common situations: A malformed FBX record whose element count is garbage, producing a negative or non-integral expected length; a code change introducing a bad element-size lookup; calling inflateZlib directly with an unvalidated length.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- zlib: unexpected end of input
- zlib: invalid header
- zlib: preset dictionary not supported
- zlib: trailing deflate data
- Unsupported FBX array encoding: ${encoding}
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/112b7b0b8421bdaa.
Report an issue: GitHub.