{"record":{"id":"76836296f0a182b0","repo":"chenhg5/cc-connect","slug":"weixin-s-response-body-exceeds-d-bytes","errorCode":null,"errorMessage":"weixin: %s: response body exceeds %d bytes","messagePattern":"weixin: (.+?): response body exceeds (.+?) bytes","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/weixin/client.go","lineNumber":112,"sourceCode":"\t}\n\n\tclient := c.httpClient\n\tif timeout > 0 {\n\t\t// Dedicated client so long-poll does not inherit short Timeout from default client.\n\t\tclient = c.longPollClient(timeout)\n\t}\n\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"weixin: %s: %w\", label, err)\n\t}\n\tdefer resp.Body.Close()\n\traw, err := io.ReadAll(io.LimitReader(resp.Body, maxIlinkHTTPResponseBody+1))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"weixin: %s: read body: %w\", label, err)\n\t}\n\tif len(raw) > maxIlinkHTTPResponseBody {\n\t\treturn nil, fmt.Errorf(\"weixin: %s: response body exceeds %d bytes\", label, maxIlinkHTTPResponseBody)\n\t}\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"weixin: %s: http %d: %s\", label, resp.StatusCode, truncateForLog(raw, 512))\n\t}\n\treturn raw, nil\n}\n\nfunc truncateForLog(b []byte, max int) string {\n\ts := string(b)\n\tif len(s) <= max {\n\t\treturn s\n\t}\n\treturn s[:max] + \"…\"\n}\n\nfunc (c *apiClient) getUpdates(ctx context.Context, buf string, timeoutMs int) (*getUpdatesResp, error) {\n\ttimeout := defaultLongPollTimeout\n\tif timeoutMs > 0 {","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/weixin/client.go#L94-L130","documentation":"post() rejects any response body larger than maxIlinkHTTPResponseBody (64 MiB). Because the read is capped with io.LimitReader(limit+1), a body of limit+1 bytes proves truncation, so the partial data is discarded rather than parsed as truncated JSON.","triggerScenarios":"An API response (most plausibly getUpdates batching many messages) exceeds 64 MiB of JSON.","commonSituations":"A huge backlog of undelivered messages delivered in one long-poll batch; pathological/misbehaving server or a wrong base_url pointing at something streaming huge payloads.","solutions":["Drain the backlog: reconnect regularly so getUpdates batches stay small","Raise maxIlinkHTTPResponseBody in platform/weixin/client.go if your workload legitimately needs larger batches (and re-test)","Confirm base_url points at the real iLink API, not an unexpected endpoint","Reduce message ingest rate or media sizes flowing through the weixin channel"],"exampleFix":"// before\nconst maxIlinkHTTPResponseBody = 64 << 20\n// after (if large batches are legitimate)\nconst maxIlinkHTTPResponseBody = 256 << 20","handlingStrategy":"validation","validationCode":"// keep getUpdates buffers small so responses stay well under the cap\nif len(pendingBuf) > 0 { /* flush/ack promptly instead of accumulating */ }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Poll frequently so getUpdates never accumulates a giant message backlog","Raise maxIlinkHTTPResponseBody only after confirming large batches are legitimate","Verify base_url points at the real API to avoid huge unexpected payloads","Bound per-message media sizes upstream of the channel"],"tags":["http","limit","payload-size","weixin"],"backgroundTag":"file-size-limit-exceeded","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}