vercel-labs/skills · error · Error
Zip entry size mismatch
Error message
Zip entry size mismatch
What it means
Thrown by readZipArchive after inflating a zip entry when the decompressed byteLength does not match the uncompressedSize declared in the entry's local/central directory header. It is a structural integrity check: the archive metadata promises N bytes but the decompressor produced a different count. This usually indicates a truncated or corrupted download, or a zip written with unusual/unsupported fields.
Source
Thrown at src/archive.ts:388
ensureRange(buffer, dataOffset, compressedSize, 'file data');
if (dataOffset + compressedSize > centralDirectory.offset) {
throw new Error('Invalid zip archive: file data overlaps central directory');
}
const compressed = buffer.subarray(dataOffset, dataOffset + compressedSize);
let contents: Buffer;
if (method === 0) {
contents = compressed;
} else if (method === 8) {
contents = inflateRawSync(compressed, {
maxOutputLength: uncompressedSize + 1,
});
} else {
throw new Error(`Unsupported zip compression method: ${method}`);
}
if (contents.byteLength !== uncompressedSize) {
throw new Error('Zip entry size mismatch');
}
if (crc32(contents) !== expectedChecksum) {
throw new Error('Zip entry checksum mismatch');
}
files.set(fileName, new Uint8Array(contents));
}
if (offset !== centralDirectory.offset + centralDirectory.size) {
throw new Error('Invalid zip central directory size');
}
return files;
}
View on GitHub (pinned to 435076e789)
Solutions
- Re-download the archive and verify its SHA/size against the source before extracting
- Test the file with an independent tool (unzip -t file.zip) to confirm corruption
- If the zip legitimately uses features the reader mishandles (e.g. data descriptors, zip64), extract it externally and point the tool at the extracted directory or a local path instead
- Report a bug if unzip -t passes but this library still fails
Example fix
# before skills add https://example.com/skills.zip # fails: Zip entry size mismatch # after curl -L -o skills.zip https://example.com/skills.zip unzip -t skills.zip # verify integrity skills add ./skills.zip
Defensive patterns
Strategy: validation
Validate before calling
// Pre-validate the archive with an independent tool before extracting
import { execFileSync } from 'node:child_process';
function assertZipIntegrity(path: string): void {
execFileSync('unzip', ['-t', path], { stdio: 'pipe' }); // throws on corrupt zip
} Type guard
null
Try / catch
try {
await extractArchive(file);
} catch (err) {
if (err instanceof Error && err.message === 'Zip entry size mismatch') {
// treat as corrupt download: delete artifact and re-fetch from source
} else throw err;
} Prevention
- Verify downloaded archive hashes against published checksums
- Always extract to a fresh temp directory so retries start clean
When it happens
Trigger: Calling extractArchive (or readZipArchive directly) on a .zip whose entry header declares an uncompressedSize that differs from the actual inflated output — typically after a partial/interrupted download, a proxy mangling the body, or a hand-crafted/nonstandard zip.
Common situations: Interrupted downloads (partial file saved), corrupted artifacts from CI caches, zips produced by exotic archivers that the minimal reader misparses, or bit-rot in cached tarballs.
Related errors
- Invalid zip archive: ${label} is out of bounds
- Zip entry checksum mismatch
- Invalid zip central directory size
- Invalid tar entry size
- Invalid zip archive: ${label} exceeds the safe integer range
AI-assisted analysis of vercel-labs/skills@435076e789 (2026-08-28).
Data as JSON: /api/errors/4355127f5d33262b.
Report an issue: GitHub.