can1357/oh-my-pi · error · ArchiveError
Invalid CAB archive: missing LZX aligned tree
Error message
Invalid CAB archive: missing LZX aligned tree
What it means
For aligned-offset blocks (type 2) with >= 3 extra bits, an aligned-offset Huffman tree must exist to decode the low 3 bits of the offset. It is null here, meaning block header setup did not build the aligned tree for this aligned block.
Source
Thrown at packages/utils/src/ar/codecs/lzx.ts:307
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++) {
const source = (this.#windowPosition - matchOffset + this.#window.byteLength) % this.#window.byteLength;
this.#writeByte(this.#window[source]!, output, outputStart + produced + index);
}
produced += matchLength;
}View on GitHub (pinned to 9690622007)
Solutions
- Use the full decompressFrame pipeline so block headers and trees are always built together.
- Verify the CAB payload integrity.
- Surface ArchiveError; decoding cannot continue without the tree.
Defensive patterns
Strategy: try-catch
Try / catch
try {
const out = decompressFrame(frame);
} catch (err) {
if (err instanceof ArchiveError && err.message.includes("missing LZX aligned tree")) {
// header/tree desync — archive corrupt
} else throw err;
} Prevention
- Always decode via the full frame pipeline so type-2 block headers build the aligned tree
- Never skip or reorder block-header parsing
- Validate archive integrity first
When it happens
Trigger: decompressFrame -> #decodeRun processes an Aligned (type 2) match with extra >= 3 while #alignedTable is null.
Common situations: Internal state desync after a corrupt header, or a stream where the aligned tree read failed silently earlier.
Related errors
- Invalid CAB archive: missing LZX decode trees
- Invalid CAB archive: truncated LZX bitstream
- Invalid CAB archive: misaligned LZX byte stream
- Invalid CAB archive: truncated LZX data
- Invalid CAB archive: invalid LZX Huffman code length
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/c6b3a757b9579c2a.
Report an issue: GitHub.