can1357/oh-my-pi · error · ArchiveError

Unsupported RAR4 compression algorithm version ${version}

Error message

Unsupported RAR4 compression algorithm version ${version}

What it means

The RAR4 decoder's decode() only implements compression algorithm versions 29 and above (the standard RAR 2.9/3.x LZSS+Huffman scheme). A file header announcing an older method (version < 29, i.e. pre-2.9 RAR) is rejected before decoding begins. The library does not ship the legacy RAR 1.5–2.x decompressors.

Source

Thrown at packages/utils/src/ar/rar/rar4-decoder.ts:156

		this.#oldDistances = [0, 0, 0, 0];
		this.#lastDistance = 0;
		this.#lastLength = 0;
		this.#previousLowDistance = 0;
		this.#lowDistanceRepeats = 0;
		this.#carriedLengths.fill(0);
		this.#filterTypes = [];
		this.#filterLengths = [];
		this.#lastFilter = 0;
	}

	decode(
		packed: Uint8Array,
		unpackedSize: number,
		dictionarySize: number,
		solid: boolean,
		version: number,
	): Uint8Array {
		if (version < 29) throw new ArchiveError(`Unsupported RAR4 compression algorithm version ${version}`);
		if (!solid) this.reset();
		const prior =
			this.#history.byteLength > dictionarySize
				? this.#history.subarray(this.#history.byteLength - dictionarySize)
				: this.#history;
		const output = new Uint8Array(prior.byteLength + unpackedSize + 260);
		output.set(prior);
		const outputStart = prior.byteLength;
		const outputEnd = outputStart + unpackedSize;
		let outputPosition = outputStart;
		const bits = new Bits(packed);
		const main = new Huffman(MAIN_SIZE);
		const distanceDecoder = new Huffman(DIST_SIZE);
		const lowDistanceDecoder = new Huffman(LOW_DIST_SIZE);
		const lengthDecoder = new Huffman(LEN_SIZE);
		const filters: PendingFilter[] = [];

		const readTables = (): void => {

View on GitHub (pinned to 9690622007)

Solutions

  1. Repack/re-compress the archive with a modern RAR (or convert to zip/7z/tar) using RAR 3+ or a third-party tool.
  2. Extract the archive with a tool that supports legacy RAR (e.g. unrar with legacy support, 7-Zip) and feed the extracted files to this library instead.
  3. Check the archive header version field to confirm; a wildly wrong value may indicate corruption rather than age.
  4. If the version field is garbage (not a plausible old version), treat the archive as corrupt.

Example fix

// before (shell)
unrar-less extraction attempt with the library on a RAR 2.0 file
// after (shell)
7z x old-archive.rar -oextracted/  # then process extracted/ contents
Defensive patterns

Strategy: validation

Validate before calling

// RAR4 file header compression version lives in the file header;
// probe with an external pre-check or reject archives known to be RAR < 2.9.
const isModern = await isRar29Plus(p); // e.g. via `unrar t -p-` or header parse
if (!isModern) throw new Error(`${p} uses legacy RAR compression (< v29); convert it first`);

Try / catch

try {
  await extractArchive(p, dest);
} catch (err) {
  if (err instanceof ArchiveError && err.message.includes("algorithm version")) {
    // fall back to an external tool (unrar/7z) or ask the user to repack
  }
  throw err;
}

Prevention

When it happens

Trigger: Decoding a RAR4 member whose compression-info version field is below 29 — typically archives created by RAR 1.5 through 2.x — passed through the archive reader's RAR4 decode path.

Common situations: Extracting very old RAR archives from the late 1990s/early 2000s; mislabeled or corrupted version fields in the file header; legacy data dumps re-shared today.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/6ed8bff3959a5e54. Report an issue: GitHub.