chenhg5/cc-connect · error
qqbot: build retry request: %w
Error message
qqbot: build retry request: %w
What it means
After a 401 and successful token refresh, apiRequestJSON rebuilds the request with http.NewRequest before retrying. If constructing that retry request fails, this error is raised. This is rare — http.NewRequest only fails on a malformed URL or an invalid method — and points at an internal URL-construction problem rather than the API itself.
Source
Thrown at platform/qqbot/qqbot.go:345
if err != nil {
return fmt.Errorf("qqbot: api request failed: %w", err)
}
defer resp.Body.Close()
// Retry once on 401
if resp.StatusCode == http.StatusUnauthorized {
if err := p.refreshToken(); err != nil {
return fmt.Errorf("qqbot: token refresh on 401: %w", err)
}
token, _ = p.getAccessToken()
if body != nil {
data, _ := json.Marshal(body)
bodyReader = bytes.NewReader(data)
}
req2, err := http.NewRequest(method, url, bodyReader)
if err != nil {
return fmt.Errorf("qqbot: build retry request: %w", err)
}
req2.Header.Set("Authorization", "QQBot "+token)
req2.Header.Set("Content-Type", "application/json")
resp2, err := core.HTTPClient.Do(req2)
if err != nil {
return fmt.Errorf("qqbot: api retry failed: %w", err)
}
defer resp2.Body.Close()
if resp2.StatusCode >= 300 {
raw, _ := io.ReadAll(resp2.Body)
return fmt.Errorf("qqbot: api %s %s returned %d (after retry): %s", method, url, resp2.StatusCode, raw)
}
if result != nil {
if err := json.NewDecoder(resp2.Body).Decode(result); err != nil {
return fmt.Errorf("qqbot: decode response: %w", err)
}View on GitHub (pinned to 4000b2338a)
Solutions
- Inspect the wrapped error — it names the URL parse failure.
- Verify the groupOpenID/userOpenID in the reply context is a valid non-empty ID.
- Check p.apiBase()/config for a malformed api_base value (missing scheme, stray spaces).
- If IDs come from an inbound event, re-check that the event was parsed correctly before replying.
Example fix
// before (config.toml) api_base = "qqbot-api.example" // after api_base = "https://api.sgroup.qq.com"
Defensive patterns
Strategy: validation
Validate before calling
u, err := url.Parse(apiBase)
if err != nil || u.Scheme == "" || u.Host == "" {
return fmt.Errorf("invalid qqbot api_base: %q", apiBase)
} Try / catch
if err := send(); err != nil {
if strings.Contains(err.Error(), "build retry request") {
slog.Error("qqbot URL construction bug", "err", err)
}
} Prevention
- Validate api_base in config parses as an absolute URL at startup.
- Never pass empty/None openIDs into URL construction; validate IDs before sending.
- Treat this error as an internal invariant violation — file a bug rather than retrying.
When it happens
Trigger: HTTP 401 received, token refresh succeeded, but http.NewRequest(method, url, ...) fails while building the retry request — a malformed endpoint URL or invalid HTTP method passed into apiRequestJSON.
Common situations: Practically only seen if p.apiBase() or a message/groupOpenID interpolated into the URL is empty or contains characters that break URL parsing; effectively an internal invariant issue.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- reasonix: create request: %w
- create request: %w
- gemini stt: create request: %w
- qwen tts: create request: %w
- qwen tts: create download request: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/20efa85f28ed27f1.
Report an issue: GitHub.