chenhg5/cc-connect · error
qq: HTTP %s read body: %w
Error message
qq: HTTP %s read body: %w
What it means
callHTTPAPI returns this when io.ReadAll fails while reading the response body of a QQ HTTP API call. The HTTP response was received (status line/headers), but the body could not be fully read — typically a mid-transfer connection reset or timeout. The action name is included to identify which API call failed.
Source
Thrown at platform/qq/qq.go:616
url := p.httpURL + "/" + action
req, err := http.NewRequest("POST", url, bytes.NewReader(body))
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
if p.token != "" {
req.Header.Set("Authorization", "Bearer "+p.token)
}
client := &http.Client{Timeout: 120 * time.Second}
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("qq: HTTP %s failed: %w", action, err)
}
defer resp.Body.Close()
raw, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("qq: HTTP %s read body: %w", action, err)
}
var apiResp struct {
Status string `json:"status"`
RetCode int `json:"retcode"`
Data json.RawMessage `json:"data"`
Message string `json:"message"`
}
if json.Unmarshal(raw, &apiResp) != nil {
return nil, fmt.Errorf("qq: HTTP %s invalid response", action)
}
if apiResp.RetCode != 0 {
return nil, fmt.Errorf("qq: HTTP %s failed (retcode=%d, msg=%s)", action, apiResp.RetCode, apiResp.Message)
}
var result map[string]any
_ = json.Unmarshal(apiResp.Data, &result)
return result, nil
}View on GitHub (pinned to 4000b2338a)
Solutions
- Retry the failed action; this is usually a transient transport error.
- Check QQ server logs for premature connection closes or crashes.
- Disable or tune keep-alive/proxy idle timeouts if errors cluster after idle periods.
- Check network stability between cc-connect and the QQ HTTP endpoint.
Example fix
// before
raw, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("qq: HTTP %s read body: %w", action, err)
}
// after (bounded read with a size cap)
raw, err := io.ReadAll(io.LimitReader(resp.Body, 8<<20))
if err != nil {
return nil, fmt.Errorf("qq: HTTP %s read body: %w", action, err)
} Defensive patterns
Strategy: retry
Try / catch
if err != nil {
if errors.Is(err, io.ErrUnexpectedEOF) || errors.Is(err, context.Canceled) {
// transient: retry the action once
}
return fmt.Errorf("qq api body read failed: %w", err)
} Prevention
- Tune proxy/load-balancer idle timeouts to exceed the 120s client timeout.
- Retry idempotent read actions on body-read errors.
- Watch for server restarts coinciding with the error in QQ server logs.
When it happens
Trigger: client.Do succeeded but io.ReadAll(resp.Body) returned an error during parseMessage's callHTTPAPI call: connection dropped mid-body, keep-alive reuse of a stale connection, or server closing the socket prematurely.
Common situations: go-cqhttp/OneBot server restarting during a request; reverse proxy (nginx) closing idle keep-alive connections; network interruption between cc-connect and the QQ server.
Related errors
- qq: HTTP %s failed: %w
- read body from %s: %w
- read body from %s: %w
- read response: %w
- gemini stt: read response: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/6cd28887705a7ae9.
Report an issue: GitHub.