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

  1. Re-download the archive and verify its SHA/size against the source before extracting
  2. Test the file with an independent tool (unzip -t file.zip) to confirm corruption
  3. 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
  4. 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

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


AI-assisted analysis of vercel-labs/skills@435076e789 (2026-08-28). Data as JSON: /api/errors/4355127f5d33262b. Report an issue: GitHub.