can1357/oh-my-pi · error · ArchiveError
Invalid ARJ method-4 compressed data: history distance is ou
Error message
Invalid ARJ method-4 compressed data: history distance is out of range
What it means
In method 4, a match's distance (positionCode) must reference bytes already emitted: positionCode < outputPosition, and the window is bounded at 26,624. The decoder throws when the distance is out of this range — referencing data that does not exist yet — because copying from it would read uninitialized output.
Source
Thrown at packages/utils/src/ar/arj.ts:149
}
if (lengthWidth !== 0) lengthCode += reader.read(lengthWidth);
if (lengthCode === 0) {
output[outputPosition++] = reader.read(8);
continue;
}
const length = lengthCode + 2;
if (length > outSize - outputPosition) {
throw new ArchiveError("Invalid ARJ method-4 compressed data: match exceeds declared size");
}
let positionCode = 0;
let positionWidth = 9;
for (; positionWidth < 13; positionWidth++) {
if (reader.read(1) === 0) break;
positionCode += 2 ** positionWidth;
}
positionCode += reader.read(positionWidth);
if (positionCode >= 26_624 || positionCode >= outputPosition) {
throw new ArchiveError("Invalid ARJ method-4 compressed data: history distance is out of range");
}
let sourcePosition = outputPosition - positionCode - 1;
for (let index = 0; index < length; index++) output[outputPosition++] = output[sourcePosition++]!;
}
reader.assertZeroPadding();
return output;
}
class ArjMemberSource implements MemberSource {
readonly #archive: Uint8Array;
readonly #start: number;
readonly #packedSize: number;
readonly #method: number;
readonly #crc: number;
constructor(archive: Uint8Array, start: number, packedSize: number, method: number, crc: number) {
this.#archive = archive;
this.#start = start;View on GitHub (pinned to 9690622007)
Solutions
- Confirm the packed payload starts at the member's first byte — starting mid-stream leaves early matches with no history and triggers this error.
- Test the member externally (`arj t` / 7-Zip); corruption here usually means the whole archive is damaged — restore from backup.
- Ensure the decompressor is fed the exact compressedSize bytes for this member only, not a region spanning adjacent members.
- If you are writing a method-4 encoder, never emit a match with distance >= bytes already produced; start streams with literal bytes.
Example fix
// before: feeding a mid-file slice into the decompressor const packed = bytes.subarray(fileOffset + 100, fileOffset + 100 + entry.compressedSize); // after: feed the member's full packed stream from its start const packed = bytes.subarray(entry.dataOffset, entry.dataOffset + entry.compressedSize); const out = decompressArjMethod4(packed, entry.originalSize);
Defensive patterns
Strategy: try-catch
Validate before calling
// Feed the decompressor the member's complete packed stream from its very first byte
if (entry.dataOffset < 0 || entry.dataOffset + entry.compressedSize > bytes.byteLength) {
throw new Error(`Member ${entry.name}: packed data out of bounds`);
}
const packed = bytes.subarray(entry.dataOffset, entry.dataOffset + entry.compressedSize); Try / catch
try {
return decompressArjMethod4(packed, originalSize);
} catch (err) {
if (err instanceof ArchiveError && err.message.includes("history distance is out of range")) {
throw new Error(`Member ${name}: corrupt back-reference — packed data likely damaged or mis-sliced`);
}
throw err;
} Prevention
- Never start decompression mid-stream; LZ back-references need full history from byte 0.
- Slice per-member payload by header offsets so streams do not span members.
- Test archives externally before batch extraction; this error usually indicates corruption.
When it happens
Trigger: decompressArjMethod4(): decoded positionCode is >= 26,624 or >= outputPosition. Happens with a match declared near the start of the stream (outputPosition too small), corrupted position-code bits, or a stream whose first bytes are not literal bytes as the format requires.
Common situations: Corrupted packed data flipping position bits, a spliced/truncated stream that starts mid-file so early matches point before the buffer, fuzzed archives probing the window bound, or an encoder bug emitting back-references before enough history exists.
Related errors
- Invalid ARJ method-4 compressed data: truncated bitstream
- Invalid ARJ method-4 compressed data: non-zero trailing bits
- Invalid ARJ method-4 compressed data: match exceeds declared
- Invalid ARJ archive: truncated ${what}
- Invalid ARJ ${field}: missing terminator
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/a91420f6983c282a.
Report an issue: GitHub.