can1357/oh-my-pi · error · ArchiveError

Invalid ZIP archive: CRC mismatch for '${memberPath}'

Error message

Invalid ZIP archive: CRC mismatch for '${memberPath}'

What it means

Thrown when the CRC-32 of the decoded member bytes does not match the CRC stored in the central directory. The member decompressed to the right size but with wrong content — silent data corruption. The library refuses to return corrupt data. ArchiveError naming the member.

Source

Thrown at packages/utils/src/ar/zip.ts:436

			const dataEnd = checkedEnd(dataStart, this.#compressedSize, this.#source.size, `data for '${memberPath}'`);
			if (this.#method === 0 && this.#compressedSize !== size) {
				throw new ArchiveError(
					`Invalid ZIP archive: size mismatch for '${memberPath}' (expected ${size}, got ${this.#compressedSize})`,
				);
			}
			const compressed = await this.#source.read(dataStart, dataEnd);
			if (compressed.byteLength !== this.#compressedSize) {
				throw new ArchiveError(`Invalid ZIP archive: truncated data for '${memberPath}'`);
			}
			const decoded = await decodeMember(compressed, this.#method, size, memberPath);
			if (decoded.byteLength !== size) {
				throw new ArchiveError(
					`Invalid ZIP archive: size mismatch for '${memberPath}' (expected ${size}, got ${decoded.byteLength})`,
				);
			}
			const actualCrc = crc32(decoded);
			if (actualCrc !== this.#crc) {
				throw new ArchiveError(`Invalid ZIP archive: CRC mismatch for '${memberPath}'`);
			}
			return decoded;
		} catch (error) {
			throw archiveError(error, `Failed to read ZIP member '${memberPath}'`);
		}
	}
}

function parseCentralDirectory(
	source: ByteSource,
	directory: Uint8Array,
	info: CentralDirectoryInfo,
	options: FormatReadOptions,
): ParsedZipEntry[] {
	const parsed: ParsedZipEntry[] = [];
	let offset = 0;
	for (let index = 0; index < info.entries; index++) {
		if (offset + 46 > directory.byteLength)

View on GitHub (pinned to 9690622007)

Solutions

  1. Re-obtain the archive and verify a published checksum (SHA-256) before use
  2. Run `unzip -t` to confirm corruption and identify affected members
  3. Re-zip from the original source files to regenerate correct CRCs
  4. Check storage health (fsck/SMART) if corruption recurs on locally stored archives

Example fix

// before
const data = await readZipMember(zip, 'report.pdf'); // throws 3717
// after: verify archive integrity first, then re-fetch if bad
// $ `unzip -t archive.zip || re-download`
const data = await readZipMember(zip, 'report.pdf');
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const data = await zip.read(member);
} catch (err) {
  if (err instanceof ArchiveError && err.message.includes('CRC mismatch')) {
    // re-download or re-zip; log the member name for telemetry
    throw new Error(`data corruption detected in ${member}; refetch archive`);
  }
  throw err;
}

Prevention

When it happens

Trigger: ZipMemberSource read where crc32(decoded) !== this.#crc after size checks pass — bit corruption in the compressed data, wrong-content substitution, or an archive whose CRC field was patched without recompressing.

Common situations: Failing disks or bad RAM corrupting stored archives; network transfers without integrity checking; zips stored on damaged media; archives edited by tools that update sizes but not CRCs.

Related errors


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