can1357/oh-my-pi · error · ArchiveError
Invalid ZIP archive: size mismatch for '${memberPath}' (expe
Error message
Invalid ZIP archive: size mismatch for '${memberPath}' (expected ${size}, got ${decoded.byteLength}) What it means
Thrown when a member decompresses successfully but its decoded byte length does not equal the uncompressed size declared in the central directory. The codec output and the metadata disagree, so the result cannot be trusted. ArchiveError reporting expected vs decoded byte counts.
Source
Thrown at packages/utils/src/ar/zip.ts:430
if (readUInt16LE(header, 8) !== this.#method) {
throw new ArchiveError(
`Invalid ZIP archive: local and central compression methods disagree for '${memberPath}'`,
);
}
const dataStart = this.#localHeaderOffset + 30 + readUInt16LE(header, 26) + readUInt16LE(header, 28);
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,View on GitHub (pinned to 9690622007)
Solutions
- Test the archive with `unzip -t` — corruption will be reported; re-obtain a clean copy
- Re-extract from the original source and re-zip
- If you produce the archive, fix the writer to set the true uncompressed size in the central directory
- Treat as untrusted input: reject the file rather than attempting salvage
Example fix
// before: trusting a repaired-by-concatenation zip
const data = await readZipMember(zip, 'a.bin'); // throws 3716
// after: verify integrity first
// $ `unzip -t suspect.zip` && unzip -o suspect.zip 'a.bin' -d out/
const data = await Bun.file('out/a.bin').bytes(); Defensive patterns
Strategy: try-catch
Try / catch
try {
const data = await zip.read(member);
} catch (err) {
if (err instanceof ArchiveError && err.message.includes('size mismatch') && err.message.includes('got')) {
throw new Error('decoded payload does not match declared size — archive untrusted/corrupt');
}
throw err;
} Prevention
- Integrity-check third-party archives (`unzip -t`) before extraction
- Reject mismatched-size archives rather than attempting salvage
- Ensure custom writers emit accurate uncompressed sizes in the central directory
- Treat size-mismatch zips from unknown sources as potentially malicious
When it happens
Trigger: ZipMemberSource read where decodeMember(...) yields decoded.byteLength !== size — corrupted compressed stream producing a different-length payload, inconsistent central-directory size fields, or data altered after compression.
Common situations: Bit-flipped or truncated-then-padded deflate streams; zips assembled from mismatched parts; archives produced by buggy compressors writing wrong uncompressed-size fields; malicious zip bombs/malformed entries.
Related errors
- Invalid ZIP archive: size mismatch for '${memberPath}' (expe
- Invalid CAB archive: CFDATA block ${block} produced ${decode
- Invalid ZIP archive: ${what} has an invalid range
- Invalid ZIP archive: missing end of central directory
- Invalid ZIP archive: missing ZIP64 end of central directory
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/1608c2b419876d0b.
Report an issue: GitHub.