vercel-labs/skills · error
Downloaded URL is not a valid SKILL.md file or supported arc
Error message
Downloaded URL is not a valid SKILL.md file or supported archive
What it means
Final fallback error in downloadSource(): the downloaded non-empty file is neither a valid SKILL.md (isValidSkillMarkdown) nor an archive that tryExtractArchive can extract. It means the URL's content type is simply unsupported by the CLI.
Source
Thrown at src/download-source.ts:286
const downloadedStats = await stat(downloadedFile);
if (downloadedStats.size === 0) {
throw new Error('Downloaded URL is empty');
}
if (await isValidSkillMarkdown(downloadedFile)) {
const skillDir = join(tempDir, 'skill');
await mkdir(skillDir, { recursive: true });
await writeFile(join(skillDir, 'SKILL.md'), await readFile(downloadedFile));
return { rootDir: skillDir, tempDir, kind: 'skill-md' };
}
await mkdir(extractDir, { recursive: true });
if (await tryExtractArchive(downloadedFile, extractDir, limits)) {
const rootDir = (await getSingleTopLevelDirectory(extractDir)) ?? extractDir;
return { rootDir, tempDir, kind: 'archive' };
}
throw new Error('Downloaded URL is not a valid SKILL.md file or supported archive');
} catch (error) {
await rm(tempDir, { recursive: true, force: true }).catch(() => {});
throw error;
}
}
View on GitHub (pinned to 435076e789)
Solutions
- Open the URL with curl and confirm it serves raw content, not HTML (use raw.githubusercontent.com for GitHub files)
- If adding a single file, ensure it is a valid SKILL.md with the required frontmatter (name, description)
- If adding an archive, use .zip or .tar.gz, which are the supported formats
- Alternatively clone the repo and run 'skills add <local-path>'
Example fix
# before skills add https://github.com/org/repo/blob/main/SKILL.md # after skills add https://raw.githubusercontent.com/org/repo/main/SKILL.md
Defensive patterns
Strategy: try-catch
Validate before calling
const head = await fetch(url);
const ct = head.headers.get('content-type') ?? '';
const ok = /text\/plain|markdown|octet-stream|zip|gzip|tar/.test(ct);
if (!ok) throw new Error(`URL serves unsupported type: ${ct}`); Type guard
function isUnsupportedDownload(e: unknown): e is Error {
return e instanceof Error && /not a valid SKILL\.md file or supported archive/.test(e.message);
} Try / catch
try { await downloadSource(url); }
catch (e) {
if (isUnsupportedDownload(e)) {
// fall back to cloning the repo and adding from a local path
const dir = await cloneRepo(gitUrlFor(url));
return addFromLocalPath(dir);
}
throw e;
} Prevention
- Always use raw file URLs, not blob/HTML pages
- Validate SKILL.md frontmatter (name, description) before publishing
- Support only .zip/.tar.gz artifacts in your registry
When it happens
Trigger: downloadSource() downloads a file, isValidSkillMarkdown() rejects it (missing frontmatter/name fields), and tryExtractArchive() returns false because the bytes are not gzip/zip/tar — then this generic error is thrown.
Common situations: Adding a URL that serves HTML (GitHub blob page instead of raw), a README.md without valid SKILL.md frontmatter, a .tar.bz2/.7z archive, or a JSON/YAML manifest the CLI does not understand.
Related errors
- Archive contains unsafe path: ${entryPath}
- Unsupported archive format
- Archive missing root SKILL.md
- Invalid zip archive: ${label} is out of bounds
- Zip entry size mismatch
AI-assisted analysis of vercel-labs/skills@435076e789 (2026-08-28).
Data as JSON: /api/errors/57b0c291b31d184f.
Report an issue: GitHub.