can1357/oh-my-pi · error · ArchiveError
Invalid CAB archive: LZX stream uses an empty Huffman tree
Error message
Invalid CAB archive: LZX stream uses an empty Huffman tree
What it means
Thrown by LzxHuffmanTable.decode when attempting to decode a symbol from a tree that was constructed with no symbols (empty === true; only possible for tables built with allowEmpty). Decoding requires reading bits and matching them to a code, which is impossible with zero symbols.
Source
Thrown at packages/utils/src/ar/codecs/lzx.ts:105
if (code + this.#counts[length]! > 2 ** length) {
throw new ArchiveError("Invalid CAB archive: oversubscribed LZX Huffman tree");
}
this.#firstCodes[length] = code;
this.#firstSymbols[length] = symbolOffset;
symbolOffset += this.#counts[length]!;
}
this.#symbols = new Uint16Array(symbolCount);
const next = this.#firstSymbols.slice();
for (let symbol = 0; symbol < lengths.byteLength; symbol++) {
const length = lengths[symbol]!;
if (length !== 0) this.#symbols[next[length]!] = symbol;
next[length]!++;
}
}
decode(reader: LzxBitReader): number {
if (this.empty) throw new ArchiveError("Invalid CAB archive: LZX stream uses an empty Huffman tree");
let code = 0;
for (let length = 1; length <= 16; length++) {
code = code * 2 + reader.readBits(1);
const relative = code - this.#firstCodes[length]!;
if (relative >= 0 && relative < this.#counts[length]!) {
return this.#symbols[this.#firstSymbols[length]! + relative]!;
}
}
throw new ArchiveError("Invalid CAB archive: invalid LZX Huffman symbol");
}
}
function readCodeLengths(reader: LzxBitReader, lengths: Uint8Array, first: number, last: number): void {
const pretreeLengths = new Uint8Array(20);
for (let index = 0; index < pretreeLengths.byteLength; index++) pretreeLengths[index] = reader.readBits(4);
const pretree = new LzxHuffmanTable(pretreeLengths);
let index = first;
while (index < last) {View on GitHub (pinned to 9690622007)
Solutions
- Re-acquire or repair the CAB archive; the stream references a tree that has no codes.
- Recompress with a standard CAB tool so referenced trees are populated.
- Confirm you are decoding with the same LZX variant (CAB LZX) the data was produced with.
Example fix
// before
const extra = this.#lengthTable.decode(reader)
// after
if (!this.#lengthTable || this.#lengthTable.empty) throw new ArchiveError("Invalid CAB archive: length tree required but empty")
const extra = this.#lengthTable.decode(reader) Defensive patterns
Strategy: try-catch
Validate before calling
if (lengthTable && lengthTable.empty) {
throw new Error('Stream references an empty length tree — archive is corrupt')
} Type guard
function isDecodable(table: LzxHuffmanTable | undefined): table is LzxHuffmanTable {
return table !== undefined && !table.empty
} Try / catch
try {
const out = decoder.decompressFrame(bytes, size)
} catch (err) {
if (err instanceof ArchiveError && err.message.includes('empty Huffman tree')) {
throw new Error('CAB archive corrupt: empty tree referenced during decode')
}
throw err
} Prevention
- Treat any decode attempt against an empty tree as archive corruption, not a recoverable state
- Reuse one LzxDecoder per folder so tree state stays consistent
- Validate CAB block checksums before decoding
When it happens
Trigger: Decoding a match length via an empty secondary length tree whose position table maps to a primary length of 7 (matchLength === NUM_PRIMARY_LENGTHS), i.e. the stream says 'read a length symbol' but the length tree has no symbols.
Common situations: Corrupted CAB archives where the length tree was encoded as all-zero but the compressed data still references it, or a compressor/decoder mismatch (e.g. a stream produced with different tree conventions).
Related errors
- Invalid CAB archive: invalid LZX Huffman code length
- Invalid CAB archive: empty LZX Huffman tree
- Invalid CAB archive: oversubscribed LZX Huffman tree
- Invalid CAB archive: invalid LZX Huffman symbol
- Invalid CAB archive: LZX code-length run exceeds its tree
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/b3d2ae935772adb6.
Report an issue: GitHub.