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
- Confirm what the artifact URL actually serves: curl -sIL <artifactUrl> | grep -i content-type, and check the extension
- Repackage/serve the artifact as .zip or .tar.gz (the only supported formats)
- Report/fix the registry entry if it points to an unsupported format
- 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
- Publish registry artifacts strictly as .zip or .tar.gz
- Set correct Content-Type headers on artifact hosts
- Check artifact extension in CI before publishing
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
- Archive contains unsafe path: ${entryPath}
- Downloaded URL is not a valid SKILL.md file or supported arc
- Unsafe archive path: ${path}
- Archive exceeds maximum unpacked size
- Archive contains too many files
AI-assisted analysis of vercel-labs/skills@435076e789 (2026-08-28).
Data as JSON: /api/errors/ed3b6c784cccdba8.
Report an issue: GitHub.