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
- Check the exact status code in the message and open the URL in a browser/curl to see the real response
- Fix the --url value (wrong tag, renamed file, removed release)
- If the asset requires auth, add the token to the URL or use an authenticated fetch path
- 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
- curl -I the URL before automating downloads
- Pin release asset URLs to immutable tags, not moving branches
- Handle private assets with authenticated requests
- Treat 5xx as retryable with backoff
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
- range chunk retries exhausted
- download exceeds --max-bytes: %d > %d
- qwen tts: download audio: %w
- download failed from all sources: %w
- too many redirects
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/545905e0dd277faa.
Report an issue: GitHub.