chenhg5/cc-connect · error
gateway response decode: %w
Error message
gateway response decode: %w
What it means
Returned when the HTTP response body from the QQ gateway endpoint cannot be decoded as JSON into the struct {url string}. Usually the body is HTML (error page), empty, or truncated instead of the expected JSON.
Source
Thrown at platform/qqbot/qqbot.go:702
func (p *Platform) getGatewayURL(token string) (string, error) {
req, err := http.NewRequest("GET", p.apiBase()+"/gateway/bot", nil)
if err != nil {
return "", err
}
req.Header.Set("Authorization", "QQBot "+token)
resp, err := core.HTTPClient.Do(req)
if err != nil {
return "", fmt.Errorf("gateway request failed: %w", err)
}
defer resp.Body.Close()
var result struct {
URL string `json:"url"`
}
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return "", fmt.Errorf("gateway response decode: %w", err)
}
if result.URL == "" {
return "", fmt.Errorf("empty gateway URL in response")
}
return result.URL, nil
}
type wsPayload struct {
Op int `json:"op"`
D json.RawMessage `json:"d,omitempty"`
S *int64 `json:"s,omitempty"`
T string `json:"t,omitempty"`
}
func (p *Platform) waitForHello(conn *websocket.Conn) error {
_ = conn.SetReadDeadline(time.Now().Add(15 * time.Second))
defer func() { _ = conn.SetReadDeadline(time.Time{}) }()
View on GitHub (pinned to 4000b2338a)
Solutions
- Log the HTTP status code and raw body on decode failure to see what was actually returned
- Check for proxy/WAF interference between the host and QQ
- Verify the access token is valid — invalid auth often yields non-JSON error bodies
- Retry; if persistent, capture the response body for a bug report
Example fix
// before
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return "", fmt.Errorf("gateway response decode: %w", err)
}
// after
raw, _ := io.ReadAll(resp.Body)
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("gateway http %d: %s", resp.StatusCode, raw)
}
if err := json.Unmarshal(raw, &result); err != nil {
return "", fmt.Errorf("gateway response decode: %w (body: %.200s)", err, raw)
} Defensive patterns
Strategy: try-catch
Validate before calling
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("gateway returned %d", resp.StatusCode)
} Try / catch
body, readErr := io.ReadAll(resp.Body)
if err := json.Unmarshal(body, &result); err != nil {
slog.Error("gateway non-JSON response", "status", resp.StatusCode, "body", string(body), "err", readErr)
return retryOrFallback()
} Prevention
- Always check status code before decoding JSON
- Log raw response bodies on decode errors
- Watch for proxy/WAF devices intercepting QQ traffic
When it happens
Trigger: json.NewDecoder(resp.Body).Decode fails because the gateway endpoint returned a non-JSON body — e.g. an HTML error page from a proxy, an empty body from a 5xx, or a WAF interception page.
Common situations: QQ returns an HTML rate-limit or WAF block page; a corporate proxy injects an auth page; server returns gzip/encoding the decoder can't handle transparently.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- qqbot: decode response: %w
- gateway request failed: %w
- decode usage response: %w
- parse JSON from %s: %w
- decode: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/d7293d6d7d48dcd1.
Report an issue: GitHub.