{"record":{"id":"676d9ba154af46b1","repo":"chenhg5/cc-connect","slug":"qq-api-s-timeout","errorCode":null,"errorMessage":"qq: API %s timeout","messagePattern":"qq: API (.+?) timeout","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/qq/qq.go","lineNumber":582,"sourceCode":"\tselect {\n\tcase raw := <-ch:\n\t\tvar resp struct {\n\t\t\tStatus  string          `json:\"status\"`\n\t\t\tRetCode int             `json:\"retcode\"`\n\t\t\tData    json.RawMessage `json:\"data\"`\n\t\t}\n\t\tif json.Unmarshal(raw, &resp) != nil {\n\t\t\treturn nil, fmt.Errorf(\"qq: invalid API response\")\n\t\t}\n\t\tif resp.RetCode != 0 {\n\t\t\treturn nil, fmt.Errorf(\"qq: API %s failed (retcode=%d)\", action, resp.RetCode)\n\t\t}\n\t\tvar result map[string]any\n\t\t_ = json.Unmarshal(resp.Data, &result)\n\t\treturn result, nil\n\n\tcase <-time.After(15 * time.Second):\n\t\treturn nil, fmt.Errorf(\"qq: API %s timeout\", action)\n\t}\n}\n\n// callHTTPAPI calls a OneBot v11 HTTP endpoint (e.g. /upload_group_file).\n// Used for file operations — avoids WebSocket message size limits and\n// file-path issues across Windows/WSL/Docker boundaries.\n// Requires http_url to be configured.\nfunc (p *Platform) callHTTPAPI(action string, params map[string]any) (map[string]any, error) {\n\tif p.httpURL == \"\" {\n\t\treturn nil, fmt.Errorf(\"qq: http_url not configured\")\n\t}\n\tbody, err := json.Marshal(params)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\turl := p.httpURL + \"/\" + action\n\treq, err := http.NewRequest(\"POST\", url, bytes.NewReader(body))\n\tif err != nil {","sourceCodeStart":564,"sourceCodeEnd":600,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/qq/qq.go#L564-L600","documentation":"Returned by callAPI when no response with the matching echo arrives within the hard-coded 15-second window (select on time.After). The request was written to the WebSocket, but the OneBot server never answered in time — the action is abandoned with this error.","triggerScenarios":"Any callAPI (Send, SendImage, resolveGroupName, Start-time calls) where the OneBot side is slow, hung, busy processing a large payload, or the echo correlation never matches because the server drops/reformats the echo field.","commonSituations":"Large base64 image uploads over WS exceeding the 15s budget; OneBot instance overloaded or rate-limited by QQ; server disconnected right after the write; a OneBot implementation that ignores or rewrites the echo field so the reply never lands in the pending channel.","solutions":["Retry the call once — transient OneBot slowness (risk control, rate limit) often resolves.","For large images, switch to the HTTP API path (callHTTPAPI) to avoid WS size/latency limits.","Verify the OneBot implementation preserves the echo field in responses; if it rewrites it, correlation breaks and every call times out.","Check OneBot server health/CPU and QQ rate-limit status; scale down message frequency.","Increase the 15s timeout (code change) if your payloads legitimately take longer."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"var lastErr error\nfor attempt := 0; attempt < 3; attempt++ {\n    result, err := p.callAPI(action, params)\n    if err == nil {\n        return result, nil\n    }\n    lastErr = err\n    if strings.Contains(err.Error(), \"timeout\") {\n        time.Sleep(time.Duration(attempt+1) * time.Second)\n        continue\n    }\n    break\n}\nreturn lastErr","preventionTips":["Route large payloads (images, files) through the HTTP API instead of WS","Confirm the OneBot implementation echoes the echo field unmodified","Monitor OneBot server load and QQ rate limits","Use idempotent actions or dedup when retrying after timeout","Consider raising the timeout for slow deployments"],"tags":["timeout","websocket","onebot","api-error"],"backgroundTag":"request-timeout","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}