Repository navigation
fix: explain latest-release fetch failures and use GITHUB_TOKEN - #7
Merged
Andrew Grathwohl (agrathwohl) merged 2 commits intoNov 5, 2026
Merged
Conversation
When no cached binary exists and the GitHub API call fails, the wrapper threw a generic "Unable to fetch latest release" error and discarded the cause, leaving users no way to tell a rate limit from a DNS or proxy failure. - Keep the underlying error (as `cause` and in the message), and call out GitHub API rate limiting with the reset time and a GITHUB_TOKEN hint. - Send GITHUB_TOKEN/GH_TOKEN to the releases API when set, so CI and shared IPs aren't capped at 60 anonymous requests/hour. A rejected token (401) falls back to an anonymous request. - Drop the Authorization header on cross-host redirects, and resolve relative Location headers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.
Bugbot Autofix is ON, but none of the reported issues met your autofix severity threshold.
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 0004a91. Configure here.
- Prefer `retry-after` for secondary limits. `x-ratelimit-reset` is sent on every response as the primary hourly window, so only show it once `x-ratelimit-remaining` is 0. - Base the token hint on whether the failing request sent Authorization (now recorded on HttpError), not on whether a token is in the environment. After a 401 anonymous retry, a rate-limited request was anonymous and should get the "set GITHUB_TOKEN" hint. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Andrew Grathwohl (agrathwohl)
approved these changes
Nov 5, 2026
Andrew Grathwohl (agrathwohl)
left a comment
There was a problem hiding this comment.
The cross-host Authorization strip and the 401 fallback were only checked against an uncommitted stub, and the repo has no test runner, so a later refactor can reopen the token leak unnoticed. Commit a small node:test file that stubs https.get and run it in CI.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Problem
On a first run (no cached binary), if the call to the GitHub releases API fails,
sfwexits with:The underlying error was discarded (
catch (_e)), so there was no way to tell a rate limit from a DNS, TLS, or proxy failure. The most likely cause in practice is rate limiting: the call is unauthenticated, and GitHub caps those at 60/hour per IP, which shared CI runners and NAT'd networks exhaust quickly.Changes
causeand appended to the message, e.g.… no valid cached release found: getaddrinfo ENOTFOUND api.github.comx-ratelimit-remaining: 0orretry-after), the message includes the reset time and suggests settingGITHUB_TOKEN. Other 403s (e.g. from a proxy) are reported as-is.GITHUB_TOKENorGH_TOKENis sent to the releases API. If GitHub rejects the token (401), the request is retried anonymously so a stale token can't break an install that works today.httpsGetnow dropsAuthorizationwhen a redirect goes to a different host, and resolves relativeLocationheaders (previously these would throw).http.tsnow rejects with anHttpErrorcarrying the status code and response headers.The background update check (when a cached binary exists) still swallows errors, as before.
Testing
npm run checkandnpm run buildpass.https.get.dist/sfw.mjswith an empty cache:GITHUB_TOKEN=<bogus>→ got a 401, retried anonymously, downloaded and ran sfw-free v1.16.0.Note:
tscalready fails onmainforprocess.env.SFW_SKIP_UPDATE_CHECK(noPropertyAccessFromIndexSignature), and the newprocess.envreads follow the same dot-access style, since Biome'suseLiteralKeysrejects bracket access. CI doesn't runtsc.🤖 Generated with Claude Code
Note
Low Risk
Changes are limited to GitHub release metadata fetching and HTTP client behavior for downloads; no auth or business-logic paths, with a security-conscious redirect fix.
Overview
First-run installs no longer fail with a generic “unable to fetch latest release” message when the GitHub releases API errors. The underlying failure is preserved as
causeand surfaced viadescribeFetchError, including tailored guidance when GitHub rate-limits (429 or rate-limit 403) with reset time and aGITHUB_TOKEN/GH_TOKENhint.fetchLatestnow sends a bearer token from those env vars when set, and retries without auth if the token gets a 401 so a bad token does not block public installs.httpsGetrejects with a structuredHttpError(status + headers) instead of a plain message, resolves relative redirectLocationvalues, and stripsAuthorizationon redirects to a different host so tokens are not sent to release CDNs.Reviewed by Cursor Bugbot for commit 0004a91. Configure here.