can1357/oh-my-pi · error · ArchiveError

Unsupported RAR4 compression method 0x${(record.method + 0x3

Error message

Unsupported RAR4 compression method 0x${(record.method + 0x30).toString(16)} for '${record.path}' / Unsupported RAR5 compression method ${record.method} for '${record.path}'

What it means

RAR4 methods are stored as 0x30-0x35 ('0'-'5') and RAR5 as 0-5; method 0 means stored. #decode rejects any record with method > 5, formatting the message per format version, because the decoder cannot inflate methods it does not implement.

Source

Thrown at packages/utils/src/ar/rar.ts:97

	async #decode(index: number): Promise<void> {
		const target = this.#records[index];
		if (!target) throw new ArchiveError("Invalid RAR member index");
		let start = index;
		if (target.solid) {
			while (start > 0 && this.#records[start]!.solid && this.#records[start - 1]!.format === target.format) start--;
		}
		const rar4Decoder = new Rar4Decoder();
		const rar5Decoder = new Rar5Decoder();
		for (let current = start; current <= index; current++) {
			const record = this.#records[current]!;
			if (record.isDirectory) continue;
			assertArchiveMemberSize(record.unpackedSize, record.path, this.#limits);
			if (record.method === 0 && record.packedSize !== record.unpackedSize) {
				corrupt("stored member size mismatch");
			}
			if (record.method > 5) {
				throw new ArchiveError(
					record.format === 4
						? `Unsupported RAR4 compression method 0x${(record.method + 0x30).toString(16)} for '${record.path}'`
						: `Unsupported RAR5 compression method ${record.method} for '${record.path}'`,
				);
			}
			if (record.method !== 0) {
				assertInMemorySize(
					record.packedSize + 2 * record.unpackedSize + 2 * record.dictionarySize + 8192,
					this.#limits,
				);
			}
			const end = checkedEnd(record.dataStart, record.packedSize, this.#source.size, "member data");
			const packed = await this.#source.read(record.dataStart, end);
			let output: Uint8Array;
			if (record.method === 0) {
				output = packed;
				if (record.solid) {
					if (record.format === 4) rar4Decoder.reset();

View on GitHub (pinned to 9690622007)

Solutions

  1. Verify with `unrar t`; if valid, the archive needs a newer extractor — use official unrar or upgrade this library
  2. Re-create the archive with standard RAR5 compression (-ma5 -m1..-m5)
  3. If corruption is suspected, re-download/re-copy the file

Example fix

// before: rar a -ma7 files/ -> method 6-7, unsupported
// after:  rar a -ma5 -m3 files/ -> methods 1-5, supported
Defensive patterns

Strategy: try-catch

Validate before calling

const unsupported = records.filter(r => r.method > 5);
if (unsupported.length) {
  throw new Error(`Archive needs a newer extractor (methods: ${unsupported.map(r => r.path).join(', ')})`);
}

Type guard

function usesSupportedMethod(record: { method: number }): boolean {
  return record.method >= 0 && record.method <= 5;
}

Try / catch

try {
  const bytes = await reader.read(memberPath);
} catch (err) {
  if (err instanceof ArchiveError && /Unsupported RAR[45]? compression method/.test(err.message)) {
    // delegate to system unrar binary or request a repacked archive
  }
  throw err;
}

Prevention

When it happens

Trigger: Decoding an archive whose member header carries compression method 6+ — either a corrupted method byte, or a RAR7/newer archive using an algorithm this library predates.

Common situations: Archives made by very new WinRAR versions; single-bit corruption in a RAR4 method byte turning 0x35 into something > 0x35.

Related errors


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