vercel-labs/skills · error

Invalid tar entry size

Error message

Invalid tar entry size

What it means

While parsing a tar header, the octal size field at offset 124 is read and parsed; if it is not a finite non-negative number the entry is malformed and 'Invalid tar entry size' is thrown, aborting extraction.

Source

Thrown at src/providers/wellknown.ts:733

  private extractTarGz(bytes: Uint8Array): Map<string, WellKnownFileContent> {
    const tar = gunzipSync(Buffer.from(bytes));
    const files = new Map<string, WellKnownFileContent>();
    const runningTotal = { bytes: 0 };
    let offset = 0;

    while (offset + 512 <= tar.length) {
      const header = tar.subarray(offset, offset + 512);
      if (header.every((byte) => byte === 0)) break;

      const name = this.readTarString(header, 0, 100);
      const sizeText = this.readTarString(header, 124, 12).trim();
      const typeFlag = header[156];
      const prefix = this.readTarString(header, 345, 155);
      const path = prefix ? `${prefix}/${name}` : name;
      const size = Number.parseInt(sizeText || '0', 8);

      if (!Number.isFinite(size) || size < 0) throw new Error('Invalid tar entry size');
      offset += 512;

      // Reject symlinks and hard links. Skip directories and metadata entries.
      if (typeFlag === 0x32 || typeFlag === 0x31) {
        throw new Error('Archive links are not supported');
      }

      const isFile = typeFlag === 0 || typeFlag === 0x30;
      if (isFile) {
        const content = tar.subarray(offset, offset + size);
        this.addArchiveFile(files, path, new Uint8Array(content), runningTotal);
      }

      offset += Math.ceil(size / 512) * 512;
    }

    if (!files.has('SKILL.md')) throw new Error('Archive missing root SKILL.md');
    return files;

View on GitHub (pinned to 435076e789)

Solutions

  1. Re-download the artifact and verify its integrity (checksum, gzip -t file.tar.gz)
  2. Confirm the artifact URL serves a real tar.gz (curl -sI and inspect Content-Type/Length)
  3. Re-publish a well-formed archive built with standard GNU/bsdtar
  4. Report registry-side corruption if it reproduces consistently
Defensive patterns

Strategy: try-catch

Validate before calling

import { gzipSync, gunzipSync } from 'node:zlib';
function looksLikeTarGz(buf: Buffer): boolean {
  try {
    const t = gunzipSync(buf);
    return t.length >= 512 && t.toString('utf8', 257, 262) === 'ustar';
  } catch { return false; }
}
if (!looksLikeTarGz(bytes)) throw new Error('payload is not a valid tar.gz');

Type guard

function isInvalidTarEntry(e: unknown): e is Error {
  return e instanceof Error && /Invalid tar entry size/.test(e.message);
}

Try / catch

try { await provider.fetchArtifact(url); }
catch (e) {
  if (isInvalidTarEntry(e)) {
    cache.bust(url); // cached corrupt copy likely
    return await provider.fetchArtifact(url); // single re-fetch
  }
  throw e;
}

Prevention

When it happens

Trigger: A corrupt or non-tar payload reaching extractTarGz: truncated downloads, gzip bombs that decode to garbage, tar headers with binary/GNU base-256 sizes the parser mishandles, or off-alignment after a previous bad entry.

Common situations: Interrupted downloads stored by a CDN; registry serving an HTML error page gzip-compressed; crafted archives designed to break naive tar parsers.

Related errors


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