can1357/oh-my-pi · error · ArchiveError

Failed to extract RAR member '${memberPath}'

Error message

Failed to extract RAR member '${memberPath}'

What it means

Thrown by the RarArchiveReader.read() when, after queuing and awaiting #decode for the requested member, the decoded bytes are absent from the cache. Since #decode always populates the cache on success, this indicates the decode failed silently or produced no entry for the index.

Source

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

	constructor(source: ByteSource, records: RarRecord[], options: FormatReadOptions) {
		this.#source = source;
		this.#records = records;
		this.#limits = options.limits;
	}

	member(index: number): MemberSource {
		return new RarMemberSource(this, index);
	}

	async read(index: number, size: number, memberPath: string): Promise<Uint8Array> {
		const pending = this.#queue.then(async () => {
			if (!this.#cache.has(index)) await this.#decode(index);
		});
		this.#queue = pending.catch(() => undefined);
		await pending;
		const bytes = this.#cache.get(index);
		if (!bytes) throw new ArchiveError(`Failed to extract RAR member '${memberPath}'`);
		if (bytes.byteLength !== size) {
			throw new ArchiveError(`RAR member '${memberPath}' size mismatch (${bytes.byteLength} != ${size})`);
		}
		return bytes.slice();
	}

	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;

View on GitHub (pinned to 9690622007)

Solutions

  1. Inspect the original decode failure: re-open the archive and read the member in a fresh reader so the real error surfaces
  2. Test the archive with `unrar t` to find the failing member
  3. Check for the companion errors (unsupported version/method, CRC mismatch) that cause #decode to fail
Defensive patterns

Strategy: try-catch

Validate before calling

// Read members in listing order and fail fast on the first error so the
// swallowed-queue path never hides the root cause:
for (const member of reader.list()) {
  await reader.read(member.path); // surfaces real decode errors immediately
}

Try / catch

try {
  const bytes = await reader.read(memberPath);
} catch (err) {
  if (err instanceof ArchiveError && err.message.startsWith('Failed to extract RAR member')) {
    // re-open the archive and retry once; the retry surfaces the real decode error
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling reader.read(memberPath) after a previous decode error was swallowed (the queue chain uses pending.catch(() => undefined)), then the cache lookup for the index returns undefined.

Common situations: Sequential reads over solid archives where an earlier member failed to decode and the error was absorbed; reading the same member twice after an internal failure.

Related errors


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