chenhg5/cc-connect · error
check updates failed (both sources): %w
Error message
check updates failed (both sources): %w
What it means
This error is returned by fetchReleases (core/updater.go:94) when BOTH release-list sources (GitHub API first, then Gitee as fallback) fail to return a valid release list. The wrapped error (`%w`) is the failure from the second (fallback) source; the primary source's error is only logged at debug level. Callers see it from CheckForUpdate, meaning no update check could be performed at all.
Source
Thrown at core/updater.go:94
url string
}
sources := []source{
{"github", githubReleasesAPI + "?per_page=20"},
{"gitee", giteeReleasesAPI + "?per_page=20&direction=desc&sort=created"},
}
if preferGitee {
sources[0], sources[1] = sources[1], sources[0]
}
releases, err := fetchReleasesFrom(sources[0].url)
if err == nil && len(releases) > 0 {
return releases, nil
}
slog.Debug("updater: primary source failed, trying fallback", "primary", sources[0].name, "error", err)
releases, err = fetchReleasesFrom(sources[1].url)
if err != nil {
return nil, fmt.Errorf("check updates failed (both sources): %w", err)
}
return releases, nil
}
func fetchReleasesFrom(apiURL string) ([]ReleaseInfo, error) {
client := &http.Client{Timeout: 15 * time.Second}
req, err := http.NewRequest("GET", apiURL, nil)
if err != nil {
return nil, err
}
req.Header.Set("User-Agent", "cc-connect-updater")
req.Header.Set("Accept", "application/json")
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()View on GitHub (pinned to 4000b2338a)
Solutions
- Check basic connectivity: `curl -sS https://api.github.com/repos/chenhg5/cc-connect/releases?per_page=1` and the Gitee equivalent to see which source and status code fails.
- Set preferGitee=true in config (or use the flag) so the Gitee mirror is tried first if GitHub is blocked in your network.
- Inspect the wrapped error text after 'both sources:' — it names the fallback failure (e.g. 'API returned 403', 'context deadline exceeded') and fix that root cause.
- If behind a proxy, set HTTPS_PROXY so both hosts are reachable, or temporarily disable automatic update checks.
- Retry later if it is a transient outage or GitHub rate limit (403 with Retry-After); rate limits reset hourly.
Example fix
// before: check fails silently on primary, error mentions only fallback
releases, err = fetchReleasesFrom(sources[1].url)
if err != nil {
return nil, fmt.Errorf("check updates failed (both sources): %w", err)
}
// after: log both errors so the root cause of each source is visible
if err != nil {
return nil, fmt.Errorf("check updates failed (primary: %v; fallback: %w)", primaryErr, err)
} Defensive patterns
Strategy: fallback
Validate before calling
func canCheckUpdates() error {
for _, u := range []string{"https://api.github.com", "https://gitee.com/api/v5"} {
c := &http.Client{Timeout: 5 * time.Second}
resp, err := c.Get(u)
if err == nil {
resp.Body.Close()
return nil
}
}
return errors.New("neither github nor gitee API reachable")
} Try / catch
if best, err := core.CheckForUpdate(version, preferGitee); err != nil {
var netErr net.Error
if errors.As(err, &netErr) || strings.Contains(err.Error(), "both sources") {
slog.Warn("update check skipped; network to release APIs unavailable", "err", err)
} else {
slog.Error("update check failed", "err", err)
}
// proceed without update — non-fatal
} Prevention
- Set preferGitee=true on networks where GitHub is blocked so the reachable mirror is tried first.
- Configure HTTPS_PROXY correctly before running upgrade/check commands.
- Skip update checks on known-offline hosts (air-gapped installs).
- Don't hammer the check — rate limits on api.github.com can take both sources out via 403s.
- Check the wrapped fallback error text first; it names the last failure cause.
When it happens
Trigger: Both fetchReleasesFrom calls fail: e.g. no network access, api.github.com blocked (common in mainland China without preferGitee), Gitee API rate-limited or returning non-200 (caught as error 916), 15s HTTP client timeout on both hosts, or both APIs returning malformed JSON that fails to decode into []ReleaseInfo.
Common situations: Developers running cc-connect behind a corporate proxy or firewall that blocks api.github.com while the Gitee fallback is also unreachable; GitHub API rate-limit (HTTP 403) when many checks originate from one IP; DNS failures on an offline host; transient network outage during `cc-connect upgrade` or startup update check.
Understand the failure class
Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.
Related errors
- API returned %d
- request failed: %w
- download failed from all sources: %w
- too many redirects
- range chunk retries exhausted
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/35660bec491b1b81.
Report an issue: GitHub.