Skip to content

fix(cli): surface GitHub API error details when skill download fails#2786

Merged
enesgules merged 4 commits into
masterfrom
fix/github-api-error-diagnostics
Jun 17, 2026
Merged

fix(cli): surface GitHub API error details when skill download fails#2786
enesgules merged 4 commits into
masterfrom
fix/github-api-error-diagnostics

Conversation

@enesgules

Copy link
Copy Markdown
Collaborator

Problem

Closes #2363

ctx7 setup and ctx7 setup --cli swallowed all GitHub API errors into a single opaque message:

✖ Failed to download find-docs skill: GitHub API error

This made it impossible for users to self-diagnose whether the failure was a 403 rate-limit, a 401 bad/expired token, or a 404 wrong branch. Users with GITHUB_TOKEN already set in their environment had no way to know their token was being accepted or rejected.

The original missing Authorization header bug was already fixed in source, but the unhelpful error messages kept users confused (see the ongoing thread in #2363).

What changed

packages/cli/src/utils/github.ts

  • extractGitHubError(response) — new private helper that reads the HTTP status and GitHub's JSON error body ({ message }) into a single descriptive string (e.g. "HTTP 403: API rate limit exceeded for 1.2.3.4"). Both fetch helpers now use it instead of duplicating the logic.
  • fetchRepoTree — returns { error: string } with the full detail instead of bare null.
  • fetchDefaultBranch — now also extracts the error body (previously discarded it). Returns { error: string; status: number } so callers can distinguish a true 404 (repo not found) from a 403/429 rate-limit — both of which previously collapsed into the same silent repo_not_found result.
  • listSkillsFromGitHub — updated to propagate the richer error and only return repo_not_found on HTTP 404.
  • downloadSkillFromGitHub — appends an actionable hint when the request was unauthenticated and the status is 403/429:
    GitHub API error: HTTP 403: API rate limit exceeded — set GITHUB_TOKEN env var to increase rate limits
    

packages/cli/src/commands/setup.ts

  • logSkillStatus(skillStatus, skillPath) — extracted shared helper that was copy-pasted identically in both setupMcp and setupCli render loops. Both loops now call it in one line.
  • Failed skill entries now show a red icon with the error detail on its own sub-line, matching the style of the CLI flow's spinner.fail(...):
    ✖ Skill failed
      ~/.claude/skills/context7-mcp
      GitHub API error: HTTP 401: Bad credentials
    
  • The EACCES permissions tip is now correctly guarded inside the skillFailed branch.

Test plan

  • ctx7 setup with a valid token → skill installs, no change in happy path output
  • ctx7 setup with an expired/invalid token → ✖ Skill failed + HTTP 401: Bad credentials
  • ctx7 setup --cli with no token, rate limited → ✖ Failed to download find-docs skill: GitHub API error: HTTP 403: ... — set GITHUB_TOKEN env var to increase rate limits
  • ctx7 setup --cli with GITHUB_TOKEN set → token is included in request, 403 hint does not appear
  • ctx7 skills install <skill> from a non-existent repo → repo_not_found (404 path unchanged)
  • ctx7 skills install <skill> from a repo that triggers a 403 → surfaces the error string instead of repo_not_found

🤖 Generated with Claude Code

enesgules and others added 4 commits June 17, 2026 12:54
…us rendering

Closes #2363

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…hint

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@enesgules enesgules merged commit acd0d46 into master Jun 17, 2026
2 checks passed
@enesgules enesgules deleted the fix/github-api-error-diagnostics branch June 17, 2026 10:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ctx7 setup --cli: downloadSkillFromGitHub missing Authorization header causes 403

2 participants