can1357/oh-my-pi · error · ArchiveError
Unsupported CAB LZX window size: ${description.parameter} bi
Error message
Unsupported CAB LZX window size: ${description.parameter} bits (expected 15-21) What it means
LZX (method 3) is supported only with window sizes of 15 to 21 bits, matching the CAB spec's legal LZX window range. A CFFOLDER whose data block's parameter (window bits) falls outside 15–21 is rejected before decoding. This protects the decoder from allocating absurd or invalid windows.
Source
Thrown at packages/utils/src/ar/cab.ts:136
this.#dataReserveSize = dataReserveSize;
this.#limits = limits;
}
readAll(): Promise<Uint8Array> {
this.#decoded ??= this.#decode();
return this.#decoded;
}
async #decode(): Promise<Uint8Array> {
const description = this.#description;
if (description.method === 2) {
throw new ArchiveError(`Unsupported CAB compression method: Quantum (level ${description.parameter})`);
}
if (description.method > 3) {
throw new ArchiveError(`Unsupported CAB compression method: ${description.method}`);
}
if (description.method === 3 && (description.parameter < 15 || description.parameter > 21)) {
throw new ArchiveError(`Unsupported CAB LZX window size: ${description.parameter} bits (expected 15-21)`);
}
const compressedSize = description.dataEnd - description.dataStart;
assertInMemorySize(compressedSize, this.#limits);
const bytes = await readExact(this.#source, description.dataStart, description.dataEnd);
let position = 0;
let outputSize = 0;
for (let block = 0; block < description.blockCount; block++) {
if (position + DATA_BLOCK_SIZE + this.#dataReserveSize > bytes.byteLength) {
throw new ArchiveError("Invalid CAB archive: truncated CFDATA header");
}
const compressed = readUInt16LE(bytes, position + 4);
const uncompressed = readUInt16LE(bytes, position + 6);
if (uncompressed === 0) throw new ArchiveError("Unsupported multi-volume CAB archive: split CFDATA block");
if (uncompressed > MAX_DATA_OUTPUT) {
throw new ArchiveError(`Invalid CAB archive: CFDATA expands to ${uncompressed} bytes (maximum 32768)`);
}
const payloadStart = position + DATA_BLOCK_SIZE + this.#dataReserveSize;View on GitHub (pinned to 9690622007)
Solutions
- Re-pack the archive with standard LZX settings (window 15–21 bits) or fall back to Deflate: recreate with lcab/MSZIP.
- Confirm with `cabextract -t file.cab` whether cabextract can read it — if yes, the file is fine but out-of-spec for this library; extract externally and repackage.
- Hex-dump the CFFOLDER to verify the parameter byte; a single flipped bit implies corruption — re-transfer.
- If producing CABs yourself, ensure your LZX compressor is configured for window ≤ 2^21 bytes.
- As an escape hatch, extract with 7z/cabextract and process the plain files instead of the CAB in-process.
Example fix
// before: out-of-spec LZX window
await openCab('odd.cab').then(r => r.readAll()); // Unsupported CAB LZX window size: 30 bits
// after: re-pack with default settings
lcab out/ repacked.cab
await openCab('repacked.cab').then(r => r.readAll()); Defensive patterns
Strategy: validation
Validate before calling
const { method, parameter } = readFolderCompression(cabBytes);
if (method === 3 && (parameter < 15 || parameter > 21))
throw new Error(`LZX window ${parameter} bits is out of spec (15-21) — re-pack the CAB`); Type guard
function isValidLzxWindow(p: number): boolean {
return Number.isInteger(p) && p >= 15 && p <= 21;
} Try / catch
try {
return await readCabArchive(bytes);
} catch (err) {
if (err instanceof ArchiveError && err.message.includes('LZX window size')) {
throw new Error('CAB uses an out-of-spec LZX window — re-pack or extract with cabextract');
}
throw err;
} Prevention
- Configure LZX compressors to standard windows (≤ 2^21).
- Sanity-check the folder parameter byte when archives come from unusual tools.
- Fall back to MSZIP/Deflate when maximum compatibility matters.
- Verify odd CABs with cabextract -t to separate corruption from nonstandard encoding.
When it happens
Trigger: readAll() on a CAB whose LZX folder declares a window size parameter < 15 or > 21 in its CFDATA/lzx parameter field.
Common situations: Corrupted typeCompress/parameter bytes in the folder header; nonstandard LZX writers using out-of-spec window bits; crafted archives probing for decoder bugs; tools that stored a quantum-level value in the LZX parameter field by mistake.
Related errors
- Unsupported CAB compression method: ${description.method}
- Unsupported CAB LZX window size: ${windowBits} bits (expecte
- Invalid CAB archive: LZX frame size ${outputSize} exceeds 32
- Invalid CAB archive: truncated data
- Invalid CAB archive: file has an invalid DOS timestamp
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/188e49132e12dead.
Report an issue: GitHub.