vercel-labs/skills · error

Archive exceeds maximum unpacked size

Error message

Archive exceeds maximum unpacked size

What it means

The well-known provider caps archive extraction at MAX_ARCHIVE_UNPACKED bytes (a zip-bomb defense). addArchiveFile accumulates content.byteLength into runningTotal.bytes and throws as soon as the cumulative unpacked size exceeds the cap.

Source

Thrown at src/providers/wellknown.ts:707

    const parts = rawPath.split('/').filter(Boolean);
    if (parts.length === 0) return null;
    if (parts.some((part) => part === '.' || part === '..')) return null;

    return parts.join('/');
  }

  private addArchiveFile(
    files: Map<string, WellKnownFileContent>,
    path: string,
    content: Uint8Array,
    runningTotal: { bytes: number }
  ) {
    const normalizedPath = this.normalizeArchivePath(path);
    if (!normalizedPath) throw new Error(`Unsafe archive path: ${path}`);

    runningTotal.bytes += content.byteLength;
    if (runningTotal.bytes > MAX_ARCHIVE_UNPACKED_BYTES) {
      throw new Error('Archive exceeds maximum unpacked size');
    }
    if (files.size >= MAX_ARCHIVE_FILES) {
      throw new Error('Archive contains too many files');
    }

    files.set(normalizedPath, content);
  }

  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;

View on GitHub (pinned to 435076e789)

Solutions

  1. If the skill legitimately needs large assets, split them out and download lazily instead of bundling in the archive
  2. Check the archive's unpacked size locally: tar -tzvf artifact.tar.gz (sizes shown)
  3. Do not raise/disable the limit — it protects the process from OOM/disk exhaustion
  4. Re-publish a slimmed artifact containing only SKILL.md plus small refs
Defensive patterns

Strategy: try-catch

Validate before calling

const head = await fetch(artifactUrl, { method: 'HEAD' });
const packed = Number(head.headers.get('content-length') ?? 0);
// gzip worst-case expansion ~1000x: refuse implausibly dense artifacts
if (packed > 0 && packed < 1024 && artifactUrl.endsWith('.tar.gz')) {
  logger.warn('suspicious compression ratio; may exceed unpacked limit');
}

Type guard

function isUnpackedSizeExceeded(e: unknown): e is Error {
  return e instanceof Error && /exceeds maximum unpacked size/i.test(e.message);
}

Try / catch

try { await provider.fetchArtifact(url); }
catch (e) {
  if (isUnpackedSizeExceeded(e)) {
    logger.warn(`Artifact ${url} too large when unpacked; skipping`);
    return null;
  }
  throw e;
}

Prevention

When it happens

Trigger: A registry artifact whose cumulative extracted byte size crosses MAX_ARCHIVE_UNPACKED_BYTES — either a legitimately huge skill (bundled models/datasets) or a decompression bomb whose small .tar.gz expands enormously.

Common situations: Skills shipping large binary assets; malicious zip bombs served from a compromised registry; highly compressible placeholder files padding an archive.

Related errors


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