can1357/oh-my-pi · error · ArchiveError

RAR member '${memberPath}' size mismatch (${bytes.byteLength

Error message

RAR member '${memberPath}' size mismatch (${bytes.byteLength} != ${size})

What it means

After successful decode, the extracted byte length is compared against the unpackedSize recorded in the member's header. A mismatch means the decoder produced a different number of bytes than the archive metadata promised, so the result cannot be trusted and read() throws.

Source

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

		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;
			assertArchiveMemberSize(record.unpackedSize, record.path, this.#limits);
			if (record.method === 0 && record.packedSize !== record.unpackedSize) {

View on GitHub (pinned to 9690622007)

Solutions

  1. Run `unrar t archive.rar` to confirm corruption and re-obtain the archive
  2. Re-download the archive; check the source storage for disk errors
  3. If you created the archive, re-create it with current WinRAR/rar tooling
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const bytes = await reader.read(memberPath);
} catch (err) {
  if (err instanceof ArchiveError && /size mismatch/.test(err.message)) {
    // treat archive as corrupt: re-fetch or recover via unrar
  }
  throw err;
}

Prevention

When it happens

Trigger: read(memberPath) on a member whose decoded output length differs from the declared unpacked size — typically from a corrupt compressed stream, a decoder bug, or metadata tampering.

Common situations: Truncated or bit-rotted archives where the stream decodes 'successfully' but short/long; archives edited by third-party tools that wrote inconsistent headers.

Related errors


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