can1357/oh-my-pi · error · ArchiveError

Invalid RAR member index

Error message

Invalid RAR member index

What it means

#decode(index) is the internal worker behind read(); it throws when this.#records[index] is undefined, i.e. the requested index does not correspond to any member found while indexing the archive.

Source

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

	}

	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;
			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}'`,

View on GitHub (pinned to 9690622007)

Solutions

  1. Upgrade/retry with the public read(memberPath) API using a path returned by the archive listing
  2. If reproducible, file a bug with the archive sample — this indicates an index/record inconsistency
Defensive patterns

Strategy: validation

Validate before calling

const members = reader.list();
const paths = new Set(members.map(m => m.path));
if (!paths.has(memberPath)) throw new Error(`Unknown member: ${memberPath}`);

Type guard

function memberExists(members: { path: string }[], path: string): boolean {
  return members.some(m => m.path === path);
}

Try / catch

try {
  const bytes = await reader.read(memberPath);
} catch (err) {
  if (err instanceof ArchiveError && err.message === 'Invalid RAR member index') {
    throw new Error(`Member not found in archive: ${memberPath}`);
  }
  throw err;
}

Prevention

When it happens

Trigger: An internal path resolving a memberPath to an index that no longer exists in the record table — effectively a lookup inconsistency between the directory listing and the records array (normally unreachable from the public API).

Common situations: Only via library bugs or misuse of internal APIs; not something a normal caller of read(memberPath) can trigger directly.

Related errors


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