can1357/oh-my-pi · error · ArchiveError
Invalid CAB archive: LZX position slot is out of range
Error message
Invalid CAB archive: LZX position slot is out of range
What it means
The decoded match's position slot indexes beyond the precomputed positionBase/extraBits tables. Valid LZX position slots are bounded by the window size; an out-of-range slot means the Huffman-decoded symbol stream is corrupt.
Source
Thrown at packages/utils/src/ar/codecs/lzx.ts:302
if (matchLength > count - produced || matchLength > this.#blockRemaining - produced) {
throw new ArchiveError("Invalid CAB archive: LZX match crosses a frame or block boundary");
}
const slot = match >>> 3;
let matchOffset: number;
if (slot === 0) {
matchOffset = this.#r0;
} else if (slot === 1) {
matchOffset = this.#r1;
this.#r1 = this.#r0;
this.#r0 = matchOffset;
} else if (slot === 2) {
matchOffset = this.#r2;
this.#r2 = this.#r0;
this.#r0 = matchOffset;
} else {
if (slot >= this.#positionBase.byteLength)
throw new ArchiveError("Invalid CAB archive: LZX position slot is out of range");
const extra = this.#extraBits[slot]!;
matchOffset = this.#positionBase[slot]! - 2;
if (this.#blockType === 2 && extra >= 3) {
if (extra > 3) matchOffset += reader.readBits(extra - 3) * 8;
if (!this.#alignedTable) throw new ArchiveError("Invalid CAB archive: missing LZX aligned tree");
matchOffset += this.#alignedTable.decode(reader);
} else if (extra !== 0) {
matchOffset += reader.readBits(extra);
}
this.#r2 = this.#r1;
this.#r1 = this.#r0;
this.#r0 = matchOffset;
}
if (matchOffset <= 0 || matchOffset > Math.min(this.#decodedSize, this.#window.byteLength)) {
throw new ArchiveError("Invalid CAB archive: LZX match offset exceeds available history");
}
for (let index = 0; index < matchLength; index++) {View on GitHub (pinned to 9690622007)
Solutions
- Re-validate/re-download the CAB archive.
- Confirm the window size used to initialize the decoder matches the folder's LZX window bits.
- Treat as unrecoverable corruption and surface ArchiveError.
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure decoder window matches folder params
function windowBitsValid(windowBits) { return windowBits >= 15 && windowBits <= 23; } Try / catch
try {
const out = decompressFrame(frame);
} catch (err) {
if (err instanceof ArchiveError && err.message.includes("position slot")) {
// bitstream desync or unsupported window — treat file as corrupt
} else throw err;
} Prevention
- Initialize the decoder with the folder's actual LZX window size
- Check archive integrity before decode
- Fail fast rather than attempting partial recovery
When it happens
Trigger: decompressFrame -> #decodeRun computes slot = match >>> 3 and slot >= positionBase.byteLength for a non-repeated-offset match.
Common situations: Corrupt CAB payloads or bitstream desync causing garbage Huffman symbols; archives compressed with parameters the decoder doesn't expect.
Related errors
- Invalid CAB archive: misaligned LZX byte stream
- Invalid CAB archive: invalid LZX Huffman code length
- Invalid CAB archive: invalid LZX repeated offset
- Invalid CAB archive: unsupported LZX block type ${this.#bloc
- Invalid CAB archive: LZX match crosses a frame or block boun
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/6b4edaf6faae3515.
Report an issue: GitHub.