{"record":{"id":"f3e98c5ebcc3a507","repo":"BabylonJS/Babylon.js","slug":"deflate-expected-byte-alignment","errorCode":null,"errorMessage":"deflate: expected byte alignment","messagePattern":"deflate: expected byte alignment","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/dev/loaders/src/FBX/parsers/zlibInflate.ts","lineNumber":128,"sourceCode":"        if (this.byteOffset + 2 > this.endOffset) {\r\n            throw new Error(\"zlib: unexpected end of input\");\r\n        }\r\n        const value = this.input[this.byteOffset] | (this.input[this.byteOffset + 1] << 8);\r\n        this.byteOffset += 2;\r\n        return value;\r\n    }\r\n\r\n    public readByte(): number {\r\n        this.ensureByteAligned();\r\n        if (this.byteOffset >= this.endOffset) {\r\n            throw new Error(\"zlib: unexpected end of input\");\r\n        }\r\n        return this.input[this.byteOffset++];\r\n    }\r\n\r\n    private ensureByteAligned(): void {\r\n        if (this.bitCount !== 0) {\r\n            throw new Error(\"deflate: expected byte alignment\");\r\n        }\r\n    }\r\n\r\n    private ensureBits(count: number): void {\r\n        while (this.bitCount < count) {\r\n            if (this.byteOffset >= this.endOffset) {\r\n                throw new Error(\"zlib: unexpected end of input\");\r\n            }\r\n            this.bitBuffer |= this.input[this.byteOffset++] << this.bitCount;\r\n            this.bitCount += 8;\r\n        }\r\n    }\r\n}\r\n\r\nclass OutputWriter {\r\n    private offset = 0;\r\n    private adlerA = 1;\r\n    private adlerB = 0;\r","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/loaders/src/FBX/parsers/zlibInflate.ts#L110-L146","documentation":"ensureByteAligned fires when a byte-oriented read (readByte or readUint16LE, used only for stored deflate blocks) is attempted while the bit reader still holds unconsumed bits in its buffer. Stored blocks in DEFLATE must start on a byte boundary; hitting this means the bit-level alignment logic and the byte-level reads got out of sync, i.e. the stream is malformed or was mis-decoded up to this point.","triggerScenarios":"readUint16LE or readByte is called when bitCount !== 0. In practice this happens only if inflateStoredBlock's alignToByte() contract is violated — i.e. corrupt preceding data caused the decoder to misinterpret block boundaries, or the internal reader state was corrupted by concurrent/shared use.","commonSituations":"Parsing a corrupted or non-deflate buffer that happened to pass the zlib header check; a modified/patched inflate pipeline that reads bits without aligning before stored blocks; sharing a BitReader across async tasks so state is interleaved.","solutions":["Confirm the payload really is a zlib stream (header check passes and it came from a standard deflate compressor).","Check any custom modifications to the inflate loop — every stored block must call alignToByte() before readUint16LE/readByte.","Ensure the BitReader is used by a single synchronous inflate call, not shared across concurrent decodes.","If the file is suspect, try decompressing it with an independent zlib implementation (e.g. pako) to confirm where the corruption starts."],"exampleFix":"// before\nreader.readBits(3); // leftover bits consumed ad hoc\nconst len = reader.readUint16LE();\n// after\nreader.alignToByte();\nconst len = reader.readUint16LE();","handlingStrategy":"try-catch","validationCode":"function isZlibStream(buf: Uint8Array): boolean {\n  return buf.byteLength >= 6 && (buf[0] & 0x0f) === 8 && ((buf[0] << 8) + buf[1]) % 31 === 0;\n}","typeGuard":null,"tryCatchPattern":"try {\n  return inflateZlib(payload, count);\n} catch (e) {\n  if (e instanceof Error && e.message === \"deflate: expected byte alignment\") {\n    throw new Error(\"payload is not a valid deflate stream (alignment error) — wrong offset or corrupt file\");\n  }\n  throw e;\n}","preventionTips":["Never share a BitReader across concurrent decodes; inflate synchronously per payload.","If you modify the inflate loop, always call alignToByte() before stored-block byte reads.","Confirm payloads come from a standard zlib compressor, not arbitrary bytes.","Use pako to bisect where a suspicious stream first diverges."],"tags":["deflate","alignment","bit-reader","corrupt-data"],"backgroundTag":"deflate-byte-alignment-error","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}