{"record":{"id":"c8342e46a91cf447","repo":"chenhg5/cc-connect","slug":"wecom-ws-media-larger-than-d-bytes","errorCode":null,"errorMessage":"wecom-ws: media larger than %d bytes","messagePattern":"wecom-ws: media larger than (.+?) bytes","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/wecom/websocket_media.go","lineNumber":359,"sourceCode":"\t\treturn nil, \"\", err\n\t}\n\tclient := &http.Client{Timeout: 90 * time.Second}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn nil, \"\", err\n\t}\n\tdefer resp.Body.Close()\n\tif resp.StatusCode < 200 || resp.StatusCode >= 300 {\n\t\treturn nil, \"\", fmt.Errorf(\"wecom-ws: download HTTP %s\", resp.Status)\n\t}\n\tfileName = parseContentDispositionFilename(resp.Header.Get(\"Content-Disposition\"))\n\tlim := io.LimitReader(resp.Body, wecomWSMediaMaxBytes+1)\n\traw, err := io.ReadAll(lim)\n\tif err != nil {\n\t\treturn nil, \"\", err\n\t}\n\tif len(raw) > wecomWSMediaMaxBytes {\n\t\treturn nil, \"\", fmt.Errorf(\"wecom-ws: media larger than %d bytes\", wecomWSMediaMaxBytes)\n\t}\n\tif aesKey != \"\" {\n\t\traw, err = wecomDecryptFile(raw, aesKey)\n\t\tif err != nil {\n\t\t\treturn nil, \"\", err\n\t\t}\n\t}\n\treturn raw, fileName, nil\n}\n\n// deliverWSMediaInbound downloads media and forwards one core.Message. Quoted media\n// is downloaded first so attachment order mirrors the quoted-context prompt.\nfunc (p *WSPlatform) deliverWSMediaInbound(body *wsMsgCallbackBody, sessionKey, chatName string, rctx wsReplyContext, current, quoted wsInboundParts, fromVoice bool) {\n\tctx, cancel := context.WithTimeout(context.Background(), 3*time.Minute)\n\tdefer cancel()\n\n\tvar images []core.ImageAttachment\n\tvar fileAtts []core.FileAttachment","sourceCodeStart":341,"sourceCodeEnd":377,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/wecom/websocket_media.go#L341-L377","documentation":"downloadWeComWSMedia reads the body through an io.LimitReader capped at wecomWSMediaMaxBytes+1; if more bytes than the cap arrive, the download is rejected with this size-limit error instead of buffering an unbounded payload into memory. It is a deliberate DoS/memory guard on WeCom websocket media downloads.","triggerScenarios":"The media URL serves a file whose size exceeds wecomWSMediaMaxBytes — e.g. a large video/document sent to the bot — and downloadWeComWSMedia is called on it.","commonSituations":"Users sending large videos or long files through WeCom; a misconfigured (too small) wecomWSMediaMaxBytes constant rejecting normal images; proxy concatenating responses.","solutions":["Raise wecomWSMediaMaxBytes if your deployment legitimately needs larger media (weigh memory use).","Surface a user-facing message that the media exceeds the supported size limit instead of retrying.","Check Content-Length before reading and reject oversized downloads early with a clear message."],"exampleFix":"// before\nconst wecomWSMediaMaxBytes = 10 << 20 // 10MB, too small for videos\n// after\nconst wecomWSMediaMaxBytes = 100 << 20 // 100MB\n// and/or: if resp.ContentLength > wecomWSMediaMaxBytes { return nil, \"\", errMediaTooLarge }","handlingStrategy":"validation","validationCode":"if resp.ContentLength > maxSupportedBytes {\n    return fmt.Errorf(\"media too large: %d > %d\", resp.ContentLength, maxSupportedBytes)\n}","typeGuard":null,"tryCatchPattern":"raw, err := downloadWeComWSMedia(url, key)\nif err != nil && strings.Contains(err.Error(), \"media larger than\") {\n    sendUserMessage(chatID, \"File exceeds the supported size limit\")\n}","preventionTips":["Check Content-Length before reading the body for early rejection.","Size wecomWSMediaMaxBytes to your real workload (e.g. allow videos).","Reject oversized uploads at the messaging layer with a clear user message."],"tags":["wecom","media-download","size-limit","http"],"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-14T05:17:10.506Z"}