chenhg5/cc-connect · error

HTTP %d

Error message

HTTP %d

What it means

downloadTuiTuiURL performs an HTTP GET via http.DefaultClient and rejects any response whose status code falls outside the 200-299 range. The error is a bare status code (e.g. "HTTP 404") with no body, so the actual server reason is lost. It exists to fail fast before reading a non-success response body.

Source

Thrown at cmd/cc-connect/tuitui.go:183

	printJSON(map[string]any{
		"ok":         true,
		"channel_id": opts.channelID,
		"parent_id":  opts.parentID,
	})
}

func downloadTuiTuiURL(ctx context.Context, rawURL string, maxBytes int64) ([]byte, string, string, error) {
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, rawURL, nil)
	if err != nil {
		return nil, "", "", err
	}
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return nil, "", "", err
	}
	defer func() { _ = resp.Body.Close() }()
	if resp.StatusCode < 200 || resp.StatusCode >= 300 {
		return nil, "", "", fmt.Errorf("HTTP %d", resp.StatusCode)
	}
	limit := maxBytes
	if limit <= 0 {
		limit = 25 << 20
	}
	if resp.ContentLength > limit {
		return nil, "", "", fmt.Errorf("download exceeds --max-bytes: %d > %d", resp.ContentLength, limit)
	}
	data, err := io.ReadAll(io.LimitReader(resp.Body, limit+1))
	if err != nil {
		return nil, "", "", err
	}
	if int64(len(data)) > limit {
		return nil, "", "", fmt.Errorf("download exceeds --max-bytes: %d > %d", len(data), limit)
	}
	mimeType := resp.Header.Get("Content-Type")
	if mimeType == "" || mimeType == "application/octet-stream" {
		mimeType = http.DetectContentType(data)

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Check the exact status code in the message and open the URL in a browser/curl to see the real response
  2. Fix the --url value (wrong tag, renamed file, removed release)
  3. If the asset requires auth, add the token to the URL or use an authenticated fetch path
  4. Retry if the code is 5xx (transient server error)

Example fix

// before: opaque error without body
return nil, "", "", fmt.Errorf("HTTP %d", resp.StatusCode)
// after: include status text and a body snippet for diagnosis
body, _ := io.ReadAll(io.LimitReader(resp.Body, 512))
return nil, "", "", fmt.Errorf("download %s: HTTP %d: %s", rawURL, resp.StatusCode, string(body))
Defensive patterns

Strategy: validation

Validate before calling

resp, err := http.Head(rawURL)
if err != nil || (resp.StatusCode < 200 || resp.StatusCode >= 300) {
	return fmt.Errorf("URL not downloadable: HTTP %v", err)
}

Type guard

func is2xx(code int) bool { return code >= 200 && code < 300 }

Try / catch

data, _, _, err := downloadTuiTuiURL(ctx, rawURL, 0)
if err != nil {
	var httpErr = err
	slog.Warn("tuitui download failed", "err", httpErr)
	return fmt.Errorf("download failed (%w); verify the URL is reachable", err)
}

Prevention

When it happens

Trigger: The remote TuiTui URL (rawURL) responds with 3xx-treated-as-error status or 4xx/5xx — e.g. a dead file link, expired signed URL, private/repo-removed asset, or the URL redirects to an endpoint returning 403/404. Called via runTuiTuiDownload with --url.

Common situations: Downloading a release asset whose tag/URL changed; Gitee/GitHub raw URL for a private repo without auth; typo'd URL; server temporarily down (502/503).

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/545905e0dd277faa. Report an issue: GitHub.