chenhg5/cc-connect · error

HTTP %d

Error message

HTTP %d

What it means

downloadLargeFile in the QQ platform adapter performs an HTTP GET of a file (e.g. an image attachment) and only accepts status 200 OK. Any other status (404, 403, 5xx, redirects to error pages) aborts the download with this bare "HTTP %d" error carrying just the numeric status code, and the message parse that needed the file fails.

Source

Thrown at platform/qq/qq.go:715

		end := strings.Index(s[idx:], "]")
		if end < 0 {
			break
		}
		s = s[idx+end+1:]
	}
	return result.String()
}

func downloadLargeFile(url string) ([]byte, string, error) {
	client := &http.Client{Timeout: 120 * time.Second}
	resp, err := client.Get(url)
	if err != nil {
		return nil, "", err
	}
	defer resp.Body.Close()

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

	data, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, "", err
	}

	mime := resp.Header.Get("Content-Type")
	if mime == "" {
		mime = http.DetectContentType(data)
	}
	return data, mime, nil
}

func downloadFile(url string) ([]byte, string, error) {
	client := &http.Client{Timeout: 30 * time.Second}
	resp, err := client.Get(url)
	if err != nil {

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Check the numeric status in the error message: 4xx means the URL/auth is bad (re-fetch the message to get a fresh media URL), 5xx means retry later.
  2. Re-download promptly after receiving the message; QQ attachment URLs are short-lived.
  3. Retry with backoff on 5xx statuses; treat 401/403/404 as non-retryable.
  4. If it persists, verify outbound network/proxy access to the QQ media host from the machine running cc-connect.

Example fix

// before
if resp.StatusCode != http.StatusOK {
	return nil, "", fmt.Errorf("HTTP %d", resp.StatusCode)
}
// after
if resp.StatusCode != http.StatusOK {
	return nil, "", fmt.Errorf("qq: download media: unexpected status %d for %s", resp.StatusCode, resp.Request.URL)
}
Defensive patterns

Strategy: retry

Validate before calling

if resp.StatusCode != http.StatusOK {
	// inspect resp.StatusCode before consuming the body
	if resp.StatusCode >= 500 { /* retry with backoff */ } else { /* URL expired/invalid: refresh media URL */ }
}

Try / catch

data, url, err := downloadFile(ctx, mediaURL)
if err != nil {
	if strings.Contains(err.Error(), "HTTP 5") {
		// transient: retry with backoff
	} else {
		// 4xx: log and skip attachment, keep processing the message
	}
}

Prevention

When it happens

Trigger: Called from parseMessage when the platform needs to download an attachment whose URL returns a non-200 response: expired/signed media URLs, deleted media, auth failures on the CDN, or the QQ media server returning 5xx.

Common situations: QQ CDN links expire quickly; a message with an old attachment URL 403s. Media deleted before download. Transient 502/503 from Tencent servers. Network proxies that inject 4xx/5xx responses.

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/22b771f81be73038. Report an issue: GitHub.