chenhg5/cc-connect · error

API returned %d

Error message

API returned %d

What it means

fetchReleasesFrom (core/updater.go:115) treats any non-200 HTTP status from the releases API as an error and returns `API returned <status>`. The library expects the GitHub/Gitee releases endpoint to reply 200 with a JSON array; anything else (403 rate limit, 404 bad repo, 5xx outage) aborts that source. On the primary source this triggers the fallback; on the fallback it surfaces inside error 915.

Source

Thrown at core/updater.go:115

}

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()

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("API returned %d", resp.StatusCode)
	}

	var releases []ReleaseInfo
	if err := json.NewDecoder(resp.Body).Decode(&releases); err != nil {
		return nil, err
	}
	return releases, nil
}

// SelfUpdate downloads and installs the given release version.
// If preferGitee is true, tries Gitee download first.
func SelfUpdate(tag string, preferGitee bool) error {
	goos := runtime.GOOS
	goarch := runtime.GOARCH

	ext := ".tar.gz"
	if goos == "windows" {
		ext = ".zip"

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Read the numeric status in the message: 403 = rate-limited (wait for the hourly reset or authenticate), 404 = wrong repo path, 5xx = server-side, retry later.
  2. Check `curl -sS -o /dev/null -w '%{http_code}' https://api.github.com/repos/chenhg5/cc-connect/releases?per_page=1` from the affected machine to reproduce.
  3. If 403 rate-limited, set preferGitee=true so checks hit Gitee instead, or reduce check frequency.
  4. Retry after a few minutes if it's a transient 5xx; the updater already falls back to the other source automatically.
  5. If 404 persists, verify the repo/API URL constants match the actual repository.

Example fix

// before: status only, no body
if resp.StatusCode != http.StatusOK {
	return nil, fmt.Errorf("API returned %d", resp.StatusCode)
}

// after: include URL and body hint for diagnosis
if resp.StatusCode != http.StatusOK {
	body, _ := io.ReadAll(io.LimitReader(resp.Body, 512))
	return nil, fmt.Errorf("API returned %d for %s: %s", resp.StatusCode, apiURL, body)
}
Defensive patterns

Strategy: retry

Validate before calling

func releasesAPIHealthy() error {
	c := &http.Client{Timeout: 10 * time.Second}
	req, _ := http.NewRequest("GET", "https://api.github.com/repos/chenhg5/cc-connect/releases?per_page=1", nil)
	req.Header.Set("User-Agent", "cc-connect-updater")
	resp, err := c.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode == 403 {
		return errors.New("GitHub API rate limited; use Gitee or wait for reset")
	}
	if resp.StatusCode != 200 {
		return fmt.Errorf("releases API status %d", resp.StatusCode)
	}
	return nil
}

Try / catch

releases, err := core.CheckForUpdate(version, preferGitee)
if err != nil {
	if strings.Contains(err.Error(), "API returned 403") {
		// rate-limited: back off and retry later
		time.Sleep(time Until next hour)
	} else if strings.Contains(err.Error(), "API returned 5") {
		// transient server error: retry with backoff
	}
}

Prevention

When it happens

Trigger: The GitHub or Gitee releases API responds with a status other than 200: GitHub API rate limiting (403, unauthenticated limit of 60 req/h per IP), repository renamed/removed (404), server-side 5xx, or Gitee returning 404 for the API path. Produced whenever fetchReleasesFrom is called by fetchReleases during CheckForUpdate.

Common situations: CI servers or office NATs sharing one IP exhausting the unauthenticated GitHub rate limit; typos or renamed org/repo making the endpoint 404; temporary GitHub/Gitee incidents; mainland-China networks where api.github.com returns errors or is intercepted.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/650eee63f033ff3a. Report an issue: GitHub.