can1357/oh-my-pi · error · ArchiveError
Invalid ARJ method-4 compressed data: truncated bitstream
Error message
Invalid ARJ method-4 compressed data: truncated bitstream
What it means
ARJ compression method 4 (the built-in variant this reader decompresses) uses an MSB-first bit reader over the packed stream. read(count) throws when the stream runs out of bits before `count` are available (or count is not an integer in 0..24), meaning the compressed data is truncated relative to what the decoder still needs.
Source
Thrown at packages/utils/src/ar/arj.ts:104
throw new ArchiveError("Invalid ARJ extended header CRC32");
}
cursor += extensionSize + 4;
assertIndexSize(cursor - offset, options.limits, "header metadata");
}
return { bodyStart, bodySize, nextOffset: cursor, metadataSize: cursor - offset, isEnd: false };
}
class ArjBitReader {
readonly #bytes: Uint8Array;
#position = 0;
constructor(bytes: Uint8Array) {
this.#bytes = bytes;
}
read(count: number): number {
if (!Number.isInteger(count) || count < 0 || count > 24 || this.#position + count > this.#bytes.byteLength * 8) {
throw new ArchiveError("Invalid ARJ method-4 compressed data: truncated bitstream");
}
let value = 0;
for (let index = 0; index < count; index++) {
const position = this.#position++;
value = value * 2 + ((this.#bytes[position >>> 3]! >>> (7 - (position & 7))) & 1);
}
return value;
}
assertZeroPadding(): void {
while (this.#position < this.#bytes.byteLength * 8) {
if (this.read(1) !== 0) throw new ArchiveError("Invalid ARJ method-4 compressed data: non-zero trailing bits");
}
}
}
function decompressArjMethod4(packed: Uint8Array, outSize: number): Uint8Array {
const reader = new ArjBitReader(packed);View on GitHub (pinned to 9690622007)
Solutions
- Check the member's compressed size in the index against the actual available bytes; re-download the archive if shorter.
- Test the archive externally (`arj t` / 7-Zip) to confirm which member is corrupt.
- Re-extract that member with a reference ARJ tool; if it also fails, the packed data is unrecoverable — restore from backup.
- If you slice packed data out yourself, copy exactly the compressedSize bytes the header declares, not a rounded or padded amount.
Example fix
// before: slicing packed bytes with a wrong length
const packed = bytes.subarray(dataStart, dataStart + guessedSize);
// after: use the declared compressed size and bounds-check against the buffer
const packed = bytes.subarray(dataStart, dataStart + entry.compressedSize);
if (packed.byteLength !== entry.compressedSize) {
throw new Error(`Member ${entry.name}: truncated packed data`);
} Defensive patterns
Strategy: validation
Validate before calling
// Ensure the member's full packed payload is present before decompressing
function packedDataComplete(bytes: Uint8Array, dataOffset: number, compressedSize: number): boolean {
return dataOffset >= 0 && compressedSize >= 0 && dataOffset + compressedSize <= bytes.byteLength;
} Try / catch
try {
return decompressArjMethod4(packed, originalSize);
} catch (err) {
if (err instanceof ArchiveError && err.message.includes("truncated bitstream")) {
throw new Error(`Member data truncated: expected ${packed.byteLength}+ bits of packed data`);
}
throw err;
} Prevention
- Slice packed payloads using the header's declared compressedSize, never guessed lengths.
- Detect truncated downloads via overall file size/sha256 before extraction.
- Keep per-member extraction failures isolated so one bad member does not abort the batch.
When it happens
Trigger: decompressArjMethod4() decodes more symbols than the packed stream can supply: packed data was truncated, outSize does not match the actual compressed stream, or the packed bytes were altered so the Huffman/LZ state machine consumes bits off the end.
Common situations: A partially downloaded or truncated member (compressed size in the header larger than the bytes actually present), a corrupted stream mid-decode, or a hand-spliced extraction where the packed payload was copied with the wrong length.
Related errors
- Invalid ARJ method-4 compressed data: non-zero trailing bits
- Invalid ARJ method-4 compressed data: match exceeds declared
- Invalid ARJ method-4 compressed data: history distance is ou
- Truncated embedded addon archive entry: ${filename}
- Invalid ARJ archive: truncated ${what}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/d8e34f01cca25716.
Report an issue: GitHub.