Summary
bootdev status intermittently fails its version check with:
Unable to check version status
Error: failed to fetch latest version
The same code path runs on every command via version.FetchUpdateInfo, so the flakiness affects more than just status.
Reproduction
Runs are non-deterministic — on my network this reproduces roughly 1 in 4 invocations:
$ for i in $(seq 1 8); do bootdev status 2>&1 | grep -E 'up to date|failed'; done
CLI up to date (v1.29.6)
CLI up to date (v1.29.6)
CLI up to date (v1.29.6)
Error: failed to fetch latest version <-- intermittent
CLI up to date (v1.29.6)
...
Root cause
version.getLatestVersion() fetches @latest from the Go module proxy. Instrumenting the swallowed error shows the real cause is a transient connection drop to proxy.golang.org:
Get "https://proxy.golang.org/github.com/bootdotdev/bootdev/@latest": read tcp ...:443: read: connection reset by peer
The function has no resilience to this:
- No retry — a single connection reset fails the whole check.
- No effective fallback — the proxy list is
[proxy.golang.org, direct], but direct is (correctly) skipped because @latest can't be fetched from it over HTTP, leaving proxy.golang.org as the only source.
- No timeout on
http.Get, so a stalled connection can hang.
- The underlying error is swallowed and the HTTP status is never checked, so the user only ever sees the generic
failed to fetch latest version message.
Proposed fix
#195 — retry transient proxy failures with backoff, add a client timeout, validate the HTTP status / response, and wrap the underlying error so the real cause is surfaced. Includes httptest-based unit tests.
Summary
bootdev statusintermittently fails its version check with:The same code path runs on every command via
version.FetchUpdateInfo, so the flakiness affects more than juststatus.Reproduction
Runs are non-deterministic — on my network this reproduces roughly 1 in 4 invocations:
Root cause
version.getLatestVersion()fetches@latestfrom the Go module proxy. Instrumenting the swallowed error shows the real cause is a transient connection drop toproxy.golang.org:The function has no resilience to this:
[proxy.golang.org, direct], butdirectis (correctly) skipped because@latestcan't be fetched from it over HTTP, leavingproxy.golang.orgas the only source.http.Get, so a stalled connection can hang.failed to fetch latest versionmessage.Proposed fix
#195 — retry transient proxy failures with backoff, add a client timeout, validate the HTTP status / response, and wrap the underlying error so the real cause is surfaced. Includes httptest-based unit tests.