can1357/oh-my-pi · error · ArchiveError
Bzip2 block exceeds its declared block-size level
Error message
Bzip2 block exceeds its declared block-size level
What it means
bzip2 blocks declare a block-size level (100KB–900KB). The decoder enforces that RLE2 'append(byte, count)' never pushes total block output past that declared limit. This error fires when a decoded BWT/RLE run length would overflow the declared block size — the stream contradicts its own header.
Source
Thrown at packages/utils/src/ar/codecs/bzip2.ts:293
let selectorIndex = 0;
let groupRemaining = 0;
let table: HuffmanTable | undefined;
const nextSymbol = (): number => {
if (groupRemaining === 0) {
if (selectorIndex >= selectors.length) {
throw new ArchiveError("Bzip2 block exhausted its Huffman selectors");
}
table = tables[selectors[selectorIndex++]!];
groupRemaining = GROUP_SIZE;
}
groupRemaining--;
return table!.decode(reader);
};
const append = (byte: number, count: number): void => {
if (count < 0 || blockLength + count > blockSizeLimit) {
throw new ArchiveError("Bzip2 block exceeds its declared block-size level");
}
block.fill(byte, blockLength, blockLength + count);
blockLength += count;
};
const endSymbol = usedBytes.length + 1;
let symbol = nextSymbol();
while (symbol !== endSymbol) {
if (symbol === 0 || symbol === 1) {
let runLength = 0;
let power = 1;
do {
runLength += symbol === 0 ? power : power * 2;
if (runLength > blockSizeLimit || power > blockSizeLimit) {
throw new ArchiveError("Invalid bzip2 RLE run length");
}
power *= 2;
symbol = nextSymbol();View on GitHub (pinned to 9690622007)
Solutions
- Test the archive with `bzip2 -t` and replace the corrupted file.
- Confirm the input passed to the decompressor starts at the 'BZh' magic — an offset stream misaligns the header and block sizes.
- If concatenating/dealing with multi-stream bz2, split on the proper stream end marker rather than arbitrary offsets.
- If this happens on trusted data, report/log the byte offset; this indicates an encoder or library bug.
Example fix
// before: offset slice skipping the BZh header const body = bytes.subarray(4); decompressBzip2(body); // after: include the full stream with its header decompressBzip2(bytes);
Defensive patterns
Strategy: try-catch
Validate before calling
const header = new TextDecoder().decode(bytes.subarray(0, 3));
if (header !== "BZh" || !(bytes[3]! >= 0x31 && bytes[3]! <= 0x39)) throw new Error("Not a bzip2 stream"); Try / catch
try {
return decompressBzip2(bytes);
} catch (err) {
if (err instanceof ArchiveError && err.message.includes("block-size")) {
throw new Error("bzip2 block data contradicts its header — archive is corrupt", { cause: err });
}
throw err;
} Prevention
- Verify the 'BZh<1-9>' header before decompressing so blockSizeLimit is derived from a real header.
- Never feed bytes from one stream/block into a decoder initialized for another.
- Run `bzip2 -t` on untrusted or transferred archives.
- Treat mismatches on trusted data as a library/encoder bug and report with the byte offset.
When it happens
Trigger: Calling append (from decodeBlockData) with a computed run count that is negative (corrupt RUNA/RUNB sequence) or pushes blockLength beyond blockSizeLimit, i.e. a corrupt bzip2 block or a mismatched blockSizeLimit derived from the stream header ('BZh9' etc.).
Common situations: Decoding damaged .bz2 data; a stream whose header level digit was altered; feeding bytes from one block into a decoder initialized for another; fuzzing/maliciously crafted archives.
Related errors
- Bzip2 block exhausted its Huffman selectors
- Corrupt compress (.Z) dictionary code ${code}
- Corrupt compress (.Z) dictionary chain
- Invalid CAB archive: misaligned LZX byte stream
- 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/199cc343ff687f65.
Report an issue: GitHub.