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

  1. Retry the failed action; this is usually a transient transport error.
  2. Check QQ server logs for premature connection closes or crashes.
  3. Disable or tune keep-alive/proxy idle timeouts if errors cluster after idle periods.
  4. 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

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


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