{"record":{"id":"ed3b6c784cccdba8","repo":"vercel-labs/skills","slug":"unsupported-archive-format","errorCode":null,"errorMessage":"Unsupported archive format","messagePattern":"Unsupported archive format","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/providers/wellknown.ts","lineNumber":661,"sourceCode":"  private extractArchive(\n    bytes: Uint8Array,\n    artifactUrl: string,\n    contentType: string\n  ): Map<string, WellKnownFileContent> {\n    if (this.isZipArchive(bytes, artifactUrl, contentType)) {\n      return new Map<string, WellKnownFileContent>(\n        readZipArchive(bytes, {\n          maxExtractedBytes: MAX_ARCHIVE_UNPACKED_BYTES,\n          maxEntries: MAX_ARCHIVE_FILES,\n        })\n      );\n    }\n\n    if (this.isTarGzArchive(bytes, artifactUrl, contentType)) {\n      return this.extractTarGz(bytes);\n    }\n\n    throw new Error('Unsupported archive format');\n  }\n\n  private isZipArchive(bytes: Uint8Array, artifactUrl: string, contentType: string): boolean {\n    return (\n      contentType.includes('application/zip') ||\n      artifactUrl.toLowerCase().endsWith('.zip') ||\n      (bytes[0] === 0x50 && bytes[1] === 0x4b)\n    );\n  }\n\n  private isTarGzArchive(bytes: Uint8Array, artifactUrl: string, contentType: string): boolean {\n    const lower = artifactUrl.toLowerCase();\n    return (\n      contentType.includes('application/gzip') ||\n      contentType.includes('application/x-gzip') ||\n      lower.endsWith('.tar.gz') ||\n      lower.endsWith('.tgz') ||\n      (bytes[0] === 0x1f && bytes[1] === 0x8b)","sourceCodeStart":643,"sourceCodeEnd":679,"githubUrl":"https://github.com/vercel-labs/skills/blob/435076e78988e1e6ec40d00b0b1d76bdbbc5419a/src/providers/wellknown.ts#L643-L679","documentation":"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'.","triggerScenarios":"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.","commonSituations":"Registry providers changing packaging format; artifacts built with xz compression for size; misconfigured Content-Type headers on the artifact host.","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"],"exampleFix":"# before: artifact is skill.tar.xz\n# after (registry side): publish skill.zip or skill.tar.gz","handlingStrategy":"validation","validationCode":"const SUPPORTED = ['.zip', '.tar.gz', '.tgz'];\nconst head = await fetch(artifactUrl, { method: 'HEAD' });\nconst ct = head.headers.get('content-type') ?? '';\nconst ok = SUPPORTED.some((s) => artifactUrl.toLowerCase().endsWith(s)) || /zip|gzip|tar/.test(ct);\nif (!ok) throw new Error(`Artifact at ${artifactUrl} is not zip/tar.gz; refusing download`);","typeGuard":"function isUnsupportedArchive(e: unknown): e is Error {\n  return e instanceof Error && /Unsupported archive format/.test(e.message);\n}","tryCatchPattern":"try { await provider.fetchArtifact(url); }\ncatch (e) {\n  if (isUnsupportedArchive(e)) return fetchFromGitSourceInstead(pkg); // fallback channel\n  throw e;\n}","preventionTips":["Publish registry artifacts strictly as .zip or .tar.gz","Set correct Content-Type headers on artifact hosts","Check artifact extension in CI before publishing"],"tags":["archive","unsupported-format","wellknown-provider","download"],"backgroundTag":"unsupported-archive-format","analyzedSha":"435076e78988e1e6ec40d00b0b1d76bdbbc5419a","analyzedAt":"2026-08-28T17:47:53.369Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}