can1357/oh-my-pi · error · ArchiveError
Invalid ${label} command Huffman table
Error message
Invalid ${label} command Huffman table What it means
readCommandTree decodes the per-block command Huffman code-length table. When a run-length skip entry (code 0/1/2) would skip past the declared number of encoded symbols, the table is corrupt or misaligned, so the library refuses to build it.
Source
Thrown at packages/utils/src/ar/lzh.ts:172
if (index + skipped > encodedCount) throw new ArchiveError(`Invalid ${label} temporary Huffman table`);
index += skipped;
}
}
return CanonicalHuffman.build(lengths, symbolCount, label);
}
function readCommandTree(reader: MsbBitReader, temporary: CanonicalHuffman, label: string): CanonicalHuffman {
const symbolCount = 510;
const encodedCount = reader.read(9);
if (encodedCount === 0) return CanonicalHuffman.single(reader.read(9), symbolCount, label);
if (encodedCount > symbolCount) throw new ArchiveError(`Invalid ${label} command Huffman table size`);
const lengths = new Uint8Array(symbolCount);
let index = 0;
while (index < encodedCount) {
const code = temporary.decode(reader);
if (code <= 2) {
const skipped = code === 0 ? 1 : code === 1 ? reader.read(4) + 3 : reader.read(9) + 20;
if (index + skipped > encodedCount) throw new ArchiveError(`Invalid ${label} command Huffman table`);
index += skipped;
} else {
lengths[index++] = code - 2;
}
}
return CanonicalHuffman.build(lengths, symbolCount, label);
}
function readPositionTree(
reader: MsbBitReader,
positionBits: number,
symbolCount: number,
label: string,
): CanonicalHuffman {
const encodedCount = reader.read(positionBits);
if (encodedCount === 0) return CanonicalHuffman.single(reader.read(positionBits), symbolCount, label);
if (encodedCount > symbolCount) throw new ArchiveError(`Invalid ${label} position Huffman table size`);
const lengths = new Uint8Array(symbolCount);View on GitHub (pinned to 9690622007)
Solutions
- Re-obtain or re-extract the archive; verify checksum/CRC of the source file
- Confirm the correct method/positionBits/positionSymbols parameters for the archive variant being decoded
- Check that decompression starts exactly at the compressed-data offset (extended headers consumed correctly)
- If the input is untrusted, expect and handle ArchiveError rather than treating it as a bug
Example fix
// before
try { out = decompressLhStatic(packed, outSize, 5, 256, "LZH -lh5-"); }
catch (e) { /* crash */ }
// after
try {
out = decompressLhStatic(packed, outSize, 5, 256, "LZH -lh5-");
} catch (e) {
if (e instanceof ArchiveError) {
console.error("Archive corrupt or unsupported variant:", e.message);
out = null;
} else throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
// Can't pre-validate Huffman tables without decoding; at minimum sanity-check input
if (packed.length === 0 || outSize <= 0) throw new Error("bad decompress inputs"); Try / catch
try {
const out = decompressLhStatic(packed, outSize, positionBits, positionSymbols, label);
} catch (err) {
if (err instanceof ArchiveError) return null; // treat member as corrupt
throw err;
} Prevention
- Verify archive integrity (CRC) before extraction
- Pass method-correct positionBits/positionSymbols parameters
- Start decoding at the true data offset after extended headers
When it happens
Trigger: Calling decompressLhStatic (via the LZH/ARJ read APIs) on a stream whose 16-bit block header or code-length table bits are corrupt, truncated-and-resumed, or whose bit reader is misaligned because an earlier field was parsed at the wrong offset.
Common situations: Corrupted archives from failed downloads or bad media; hand-crafted/fuzzed archives; using the wrong method label/dictionary size for a variant (e.g. ARJ method 1-3 vs -lh5-..-lh7-), which shifts bit boundaries.
Related errors
- Invalid ${label} Huffman table: oversubscribed codes
- Invalid ${label} Huffman table: incomplete codes
- Invalid ${label} Huffman table: prefix collision
- Invalid ${label} Huffman table: duplicate code
- Invalid ${this.#label} Huffman code
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/9f589e0593561e3c.
Report an issue: GitHub.