Tencent/WeKnora · error
decode qqbot response: %w
Error message
decode qqbot response: %w
What it means
The QQ bot API returned a 2xx status but the body could not be decoded into the expected response struct. doJSON wraps the json.Decoder error with this message so the root JSON parse cause is preserved.
Source
Thrown at internal/im/qqbot/client.go:172
return err
}
req.Header.Set("Authorization", "QQBot "+token)
}
resp, err := c.httpClient.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return fmt.Errorf("qqbot api %s %s failed: %s", method, url, resp.Status)
}
if out == nil {
return nil
}
if err := json.NewDecoder(resp.Body).Decode(out); err != nil {
return fmt.Errorf("decode qqbot response: %w", err)
}
return nil
}
func (c *Client) AccessToken(ctx context.Context) (string, error) {
c.mu.Lock()
if c.accessToken != "" && time.Until(c.expiresAt) > time.Minute {
token := c.accessToken
c.mu.Unlock()
return token, nil
}
c.mu.Unlock()
body := map[string]string{
"appId": c.appID,
"clientSecret": c.clientSecret,
}
var result tokenResponseView on GitHub (pinned to 988cbb0330)
Solutions
- Log the raw response body to see what was actually returned
- Check for a proxy/CDN intercepting the request and bypass it
- Upgrade the library if the QQ API response schema changed
- Retry the request — transient truncation can produce this
Example fix
// before
if err := json.NewDecoder(resp.Body).Decode(out); err != nil { return err } // opaque
// after
body, _ := io.ReadAll(resp.Body)
if err := json.Unmarshal(body, out); err != nil {
return fmt.Errorf("decode qqbot response: %w; body=%s", err, body)
} Defensive patterns
Strategy: try-catch
Validate before calling
// verify endpoint reachability and that it returns JSON before decoding
resp, _ := http.Get(apiBase + "/gateway")
ct := resp.Header.Get("Content-Type")
if !strings.Contains(ct, "application/json") {
return fmt.Errorf("unexpected content-type %q (proxy error page?)", ct)
} Try / catch
if err := json.NewDecoder(resp.Body).Decode(out); err != nil {
body, _ := io.ReadAll(io.MultiReader(...)) // capture body for diagnostics
return fmt.Errorf("decode qqbot response: %w", err)
} Prevention
- Log raw response bodies on decode failure
- Check Content-Type before decoding
- Bypass intercepting proxies for API calls
- Pin/upgrade client when QQ changes schemas
When it happens
Trigger: GatewayURL, sendText, or AccessToken receives a 2xx response whose body is HTML (proxy error page), truncated, empty, or whose shape changed.
Common situations: Corporate proxy/gateway returning HTML with 200; QQ API response schema drift; interrupted connection truncating the body; hitting a wrong endpoint that returns 200 with a different payload.
Related errors
- failed to decode API response: %w
- unmarshal page: %w
- qqbot api %s %s failed: %s
- parse qqbot credentials: %w
- http decode read response: %w
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/c0b66be9419f53c9.
Report an issue: GitHub.