{"record":{"id":"397b317f6b00b888","repo":"upstash/context7","slug":"failed-to-download-skill-name-downloaddata-e","errorCode":null,"errorMessage":"Failed to download ${skill.name}: ${downloadData.error}","messagePattern":"Failed to download (.+?): (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/cli/src/commands/skill.ts","lineNumber":417,"sourceCode":"    log.warn(\"Installation cancelled\");\n    return;\n  }\n\n  const targetDirs = getTargetDirs(targets);\n\n  const installSpinner = ora(\"Installing skills...\").start();\n\n  let permissionError = false;\n  const failedDirs: Set<string> = new Set();\n  const installedSkills: string[] = [];\n\n  for (const skill of selectedSkills) {\n    try {\n      installSpinner.text = `Downloading ${skill.name}...`;\n      const downloadData = await downloadSkill(skill.project, skill.name);\n\n      if (downloadData.error) {\n        log.warn(`Failed to download ${skill.name}: ${downloadData.error}`);\n        continue;\n      }\n\n      installSpinner.text = `Installing ${skill.name}...`;\n\n      const [primaryDir, ...symlinkDirs] = targetDirs;\n\n      try {\n        await installSkillFiles(skill.name, downloadData.files, primaryDir);\n      } catch (dirErr) {\n        const error = dirErr as NodeJS.ErrnoException;\n        if (error.code === \"EACCES\" || error.code === \"EPERM\") {\n          permissionError = true;\n          failedDirs.add(primaryDir);\n        }\n        throw dirErr;\n      }\n","sourceCodeStart":399,"sourceCodeEnd":435,"githubUrl":"https://github.com/upstash/context7/blob/5284672feb575908efead6fcf1b5e542f8d607bb/packages/cli/src/commands/skill.ts#L399-L435","documentation":"Emitted in the install loop of `context7 skill add` (interactive flow). Each selected skill is fetched via downloadSkill(project, name), which first calls the Context7 registry (getSkill) and, on failure, falls back to GitHub. If both paths return an error, downloadData.error is printed with log.warn and the loop continues to the next skill — one failed download does not abort the batch.","triggerScenarios":"Skill or project name that does not exist in the registry (404 from getSkill) AND has no reachable GitHub fallback; GitHub fallback failing with 403/429 rate limit when unauthenticated; invalid skill GitHub URL; skill path containing zero files; network/DNS failure reaching context7.com or api.github.com.","commonSituations":"Anonymous GitHub API rate limits (60 req/hr) on CI or shared IPs breaking the fallback; skill removed/renamed in the registry since the picker cached it; private-repo skills fetched without authorization; corporate proxies blocking api.github.com.","solutions":["Re-run using the exact project/skill ID shown by `context7 skill search <query>`","If the error mentions 403/429 or rate: run `gh auth login` or export GITHUB_TOKEN before retrying","Check connectivity: curl -I https://context7.com and curl -I https://api.github.com","For private skills, ensure the GitHub account/token has access to the source repository"],"exampleFix":"# before — anonymous, fallback hits GitHub rate limit\ncontext7 skill add\n\n# after — authenticated, higher rate limit\ngh auth login\n# or: export GITHUB_TOKEN=ghp_xxx\ncontext7 skill add","handlingStrategy":"validation","validationCode":"// pre-flight: confirm the skill resolves before batch install\n// CLI: context7 skill info <project>/<name>  (exits non-zero if missing)\n// API-equivalent in code:\nconst res = await fetch(`https://context7.com/api/v1/skills/${project}/${name}`);\nif (!res.ok) skip(name, `registry ${res.status}`);","typeGuard":"function isDownloadOk(r: { files?: unknown[]; error?: string }): r is { files: NonNullable<typeof r.files> } {\n  return !r.error && Array.isArray(r.files) && r.files.length > 0;\n}","tryCatchPattern":null,"preventionTips":["Run `gh auth login` or set GITHUB_TOKEN before bulk installs to survive the GitHub fallback","Install by exact IDs taken from `context7 skill search` output","On CI, verify egress to context7.com and api.github.com first"],"tags":["network","api","github","rate-limit","skills","download"],"backgroundTag":"package-download-failed","analyzedSha":"5284672feb575908efead6fcf1b5e542f8d607bb","analyzedAt":"2026-08-18T18:00:18.510Z","schemaVersion":2},"datasetVersion":"2026-08-24T22:17:12.610Z"}