{"record":{"id":"78a2320a9662e585","repo":"chenhg5/cc-connect","slug":"resource-too-large-total-d-exceeds-cap-d","errorCode":null,"errorMessage":"resource too large: total=%d exceeds cap %d","messagePattern":"resource too large: total=(.+?) exceeds cap (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/feishu/resource_download.go","lineNumber":127,"sourceCode":"\tif err != nil {\n\t\t// Fallback: try a single plain GET. Some servers reject Range entirely\n\t\t// with 4xx instead of silently ignoring it.\n\t\tslog.Warn(p.tag()+\": first-chunk fetch failed; trying plain GET\",\n\t\t\t\"error\", err, \"file_key\", fileKey, \"type\", resType)\n\t\treturn p.resourceSingleGet(ctx, token, messageID, fileKey, resType)\n\t}\n\n\t// Server ignored our Range header and sent the whole body in one 200.\n\tif total == 0 {\n\t\tif int64(len(first)) > p.resourceMaxBytes {\n\t\t\treturn nil, fmt.Errorf(\"resource too large: body=%d exceeds cap %d\", len(first), p.resourceMaxBytes)\n\t\t}\n\t\treturn first, nil\n\t}\n\n\t// Server honoured Range. Loop the remaining chunks.\n\tif total > p.resourceMaxBytes {\n\t\treturn nil, fmt.Errorf(\"resource too large: total=%d exceeds cap %d\", total, p.resourceMaxBytes)\n\t}\n\tif int64(len(first)) >= total {\n\t\t// Defensive: a server that advertises 206 with first slice already\n\t\t// covering the whole resource is fine — return what we have.\n\t\treturn first, nil\n\t}\n\treturn p.resourceFetchRemainingChunks(ctx, token, messageID, fileKey, resType, total, first)\n}\n\n// resourceFetchFirstChunk issues Range bytes=0-0 to learn the total and grab\n// the first byte. Returns (first, total, nil) where total==0 means the\n// server ignored Range and the entire body is in `first`.\nfunc (p *Platform) resourceFetchFirstChunk(ctx context.Context, token, messageID, fileKey, resType string) ([]byte, int64, error) {\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, p.resourceURL(messageID, fileKey, resType), nil)\n\tif err != nil {\n\t\treturn nil, 0, fmt.Errorf(\"build first-chunk request: %w\", err)\n\t}\n\treq.Header.Set(\"Authorization\", \"Bearer \"+token)","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/feishu/resource_download.go#L109-L145","documentation":"Thrown before any chunk loop begins when the server honoured the Range probe (206) and advertised a Content-Range total that exceeds resourceMaxBytes. This is an early-exit guard so the library never starts downloading a file it cannot hold in memory. The advertised total and the cap are both in the message.","triggerScenarios":"First-chunk probe returns 206 with Content-Range 'bytes 0-0/N' where N > p.resourceMaxBytes; resourceDownloadStream aborts before fetching remaining chunks.","commonSituations":"A user sends a file larger than the configured cap (e.g. 200 MB file against default cap); or resource_max_bytes was lowered in config and previously-working files now exceed it.","solutions":["Increase resource_max_bytes if the bot has memory headroom for larger files","Reject or short-circuit earlier: check Feishu message metadata for size before calling download","Ask the sender to compress or share a link for oversized files"],"exampleFix":"// before (config.toml)\n# resource_max_bytes = 33554432\n// after\n[platform.feishu]\nresource_max_bytes = 268435456  # 256 MiB","handlingStrategy":"validation","validationCode":"if total, err := probeSize(msgID, key); err == nil && total > maxResourceBytes { skipDownload(\"declared size too large\") }","typeGuard":"null","tryCatchPattern":"if _, err := download(ctx, ...); err != nil && strings.Contains(err.Error(), \"total=\") {\n    slog.Warn(\"file exceeds cap; rejected pre-download\", \"err\", err)\n}","preventionTips":["Keep resource_max_bytes above the largest expected upload; document it for users","Check Feishu message resource metadata for size before download when available","Cap bot memory budget; the cap exists to prevent OOM — don't raise it blindly","Handle the error as a user-facing 'file too large' message, not a crash"],"tags":["go","feishu","file-size","range-request"],"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"}