vercel-labs/skills · error · Error
Download is larger than ${limits.downloadMaxBytes} bytes. Se
Error message
Download is larger than ${limits.downloadMaxBytes} bytes. Set SKILLS_DOWNLOAD_MAX_BYTES to override. What it means
Before streaming the body, downloadToFile checks the Content-Length header against limits.downloadMaxBytes and throws if the server-declared size already exceeds the cap. This is an early exit so a huge file is never downloaded at all. The limit is tunable via SKILLS_DOWNLOAD_MAX_BYTES.
Source
Thrown at src/download-source.ts:98
async function downloadToFile(
url: string,
targetFile: string,
limits: DownloadLimits
): Promise<void> {
const response = await fetch(url, {
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
redirect: 'follow',
});
if (!response.ok) {
throw new Error(`Download failed with HTTP ${response.status}`);
}
const contentLength = response.headers.get('content-length');
if (contentLength) {
const parsed = Number.parseInt(contentLength, 10);
if (Number.isFinite(parsed) && parsed > limits.downloadMaxBytes) {
throw new Error(
`Download is larger than ${limits.downloadMaxBytes} bytes. Set SKILLS_DOWNLOAD_MAX_BYTES to override.`
);
}
}
if (!response.body) {
throw new Error('Download response has no body');
}
let downloaded = 0;
const limitStream = new TransformStream<Uint8Array, Uint8Array>({
transform(chunk, controller) {
downloaded += chunk.byteLength;
if (downloaded > limits.downloadMaxBytes) {
throw new Error(
`Download is larger than ${limits.downloadMaxBytes} bytes. Set SKILLS_DOWNLOAD_MAX_BYTES to override.`
);
}View on GitHub (pinned to 435076e789)
Solutions
- Check the file size first: curl -sI <url> | grep -i content-length
- If the file is trusted and legitimately large, raise the cap: SKILLS_DOWNLOAD_MAX_BYTES=1048576000 skills add <url>
- Use a slimmer archive or a git source that fetches only needed paths
- Confirm you didn't accidentally point at a full-repo or monorepo snapshot
Example fix
# before skills add https://example.com/all-skills.zip # Download is larger than max bytes # after SKILLS_DOWNLOAD_MAX_BYTES=1048576000 skills add https://example.com/all-skills.zip
Defensive patterns
Strategy: validation
Validate before calling
// Compare Content-Length against your budget before calling the API
async function assertWithinBudget(url: string, maxBytes: number): Promise<void> {
const res = await fetch(url, { method: 'HEAD' });
const len = Number(res.headers.get('content-length'));
if (Number.isFinite(len) && len > maxBytes) {
throw new Error(`Artifact too large: ${len} > ${maxBytes}`);
}
} Type guard
null
Try / catch
try {
await downloadSource(url);
} catch (err) {
if (err instanceof Error && err.message.includes('SKILLS_DOWNLOAD_MAX_BYTES')) {
// either raise the env limit or choose a smaller artifact
} else throw err;
} Prevention
- Publish slim per-skill archives instead of monolithic bundles
- Export SKILLS_DOWNLOAD_MAX_BYTES explicitly in automation scripts
When it happens
Trigger: Downloading a URL whose Content-Length exceeds the configured download budget — e.g. a release asset of several hundred MB when the cap is lower, or a user-lowered SKILLS_DOWNLOAD_MAX_BYTES.
Common situations: Skill archives that bundle heavy assets, mirrors serving full repo snapshots, or environments where the default budget is too small for the artifact being fetched.
Related errors
- Archive contains too many files (${state.entries}). Maximum
- Archive extracts to more than ${limits.extractMaxBytes} byte
- Download failed with HTTP ${response.status}
- Download response has no body
- Archive contains unsafe path: ${entryPath}
AI-assisted analysis of vercel-labs/skills@435076e789 (2026-08-28).
Data as JSON: /api/errors/117e10849e641908.
Report an issue: GitHub.