vercel-labs/skills · error

Unsupported archive format

Error message

Unsupported archive format

What it means

The WellKnownProvider's archive extractor only supports ZIP and TAR.GZ. After downloading a skill artifact, if the Content-Type is not zip-ish and the URL doesn't end in .zip, and the tar.gz sniff fails, it throws 'Unsupported archive format'.

Source

Thrown at src/providers/wellknown.ts:661

  private extractArchive(
    bytes: Uint8Array,
    artifactUrl: string,
    contentType: string
  ): Map<string, WellKnownFileContent> {
    if (this.isZipArchive(bytes, artifactUrl, contentType)) {
      return new Map<string, WellKnownFileContent>(
        readZipArchive(bytes, {
          maxExtractedBytes: MAX_ARCHIVE_UNPACKED_BYTES,
          maxEntries: MAX_ARCHIVE_FILES,
        })
      );
    }

    if (this.isTarGzArchive(bytes, artifactUrl, contentType)) {
      return this.extractTarGz(bytes);
    }

    throw new Error('Unsupported archive format');
  }

  private isZipArchive(bytes: Uint8Array, artifactUrl: string, contentType: string): boolean {
    return (
      contentType.includes('application/zip') ||
      artifactUrl.toLowerCase().endsWith('.zip') ||
      (bytes[0] === 0x50 && bytes[1] === 0x4b)
    );
  }

  private isTarGzArchive(bytes: Uint8Array, artifactUrl: string, contentType: string): boolean {
    const lower = artifactUrl.toLowerCase();
    return (
      contentType.includes('application/gzip') ||
      contentType.includes('application/x-gzip') ||
      lower.endsWith('.tar.gz') ||
      lower.endsWith('.tgz') ||
      (bytes[0] === 0x1f && bytes[1] === 0x8b)

View on GitHub (pinned to 435076e789)

Solutions

  1. Confirm what the artifact URL actually serves: curl -sIL <artifactUrl> | grep -i content-type, and check the extension
  2. Repackage/serve the artifact as .zip or .tar.gz (the only supported formats)
  3. Report/fix the registry entry if it points to an unsupported format
  4. As a workaround, fetch the skill from its git source instead of the well-known registry

Example fix

# before: artifact is skill.tar.xz
# after (registry side): publish skill.zip or skill.tar.gz
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED = ['.zip', '.tar.gz', '.tgz'];
const head = await fetch(artifactUrl, { method: 'HEAD' });
const ct = head.headers.get('content-type') ?? '';
const ok = SUPPORTED.some((s) => artifactUrl.toLowerCase().endsWith(s)) || /zip|gzip|tar/.test(ct);
if (!ok) throw new Error(`Artifact at ${artifactUrl} is not zip/tar.gz; refusing download`);

Type guard

function isUnsupportedArchive(e: unknown): e is Error {
  return e instanceof Error && /Unsupported archive format/.test(e.message);
}

Try / catch

try { await provider.fetchArtifact(url); }
catch (e) {
  if (isUnsupportedArchive(e)) return fetchFromGitSourceInstead(pkg); // fallback channel
  throw e;
}

Prevention

When it happens

Trigger: A well-known registry artifact served as .tar.bz2, .7z, .tar.xz, or with an unexpected Content-Type (e.g. application/octet-stream for a .tar.xz) — isZipArchive() and isTarGzArchive() both return false.

Common situations: Registry providers changing packaging format; artifacts built with xz compression for size; misconfigured Content-Type headers on the artifact host.

Related errors


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