{"record":{"id":"73f72fa14d454edc","repo":"chenhg5/cc-connect","slug":"s-image-download-w","errorCode":null,"errorMessage":"%s: image download: %w","messagePattern":"(.+?): image download: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/feishu/feishu.go","lineNumber":3423,"sourceCode":"\tswitch msgType {\n\tcase larkim.MsgTypeAudio:\n\t\treturn (&larkim.MessageAudio{FileKey: fileKey}).String()\n\tcase larkim.MsgTypeMedia:\n\t\treturn (&larkim.MessageMedia{FileKey: fileKey}).String()\n\tdefault:\n\t\treturn (&larkim.MessageFile{FileKey: fileKey}).String()\n\t}\n}\n\nfunc (p *Platform) downloadImage(messageID, imageKey string) ([]byte, string, error) {\n\t// Issue #1741: large image bodies suffer the same code=234037 truncation\n\t// as files when fetched through the larkim SDK (which cannot set Range\n\t// headers). Route image downloads through the same chunked helper used\n\t// for files so a 20-MiB screenshot lands whole instead of being capped\n\t// at the SDK's ~2 MiB streaming ceiling.\n\tdata, err := p.downloadResourceChunked(context.Background(), messageID, imageKey, \"image\")\n\tif err != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"%s: image download: %w\", p.tag(), err)\n\t}\n\n\tmimeType := detectMimeType(data)\n\tslog.Debug(p.tag()+\": downloaded image\", \"key\", imageKey, \"size\", len(data), \"mime\", mimeType)\n\treturn data, mimeType, nil\n}\n\nfunc (p *Platform) downloadResource(messageID, fileKey, resType string) ([]byte, error) {\n\t// Issue #1741: the larkim SDK issues a plain GET that Feishu truncates\n\t// with code=234037 for resources above ~2 MiB. downloadResourceChunked\n\t// bypasses the SDK, sends Range headers, and reassembles the bytes\n\t// client-side. All four existing call sites (audio body, file body,\n\t// merge_forward file, #1588 quoted file) flow through here unchanged.\n\tdata, err := p.downloadResourceChunked(context.Background(), messageID, fileKey, resType)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tslog.Debug(p.tag()+\": downloaded resource\", \"key\", fileKey, \"type\", resType, \"size\", len(data))","sourceCodeStart":3405,"sourceCodeEnd":3441,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/feishu/feishu.go#L3405-L3441","documentation":"Wraps a failure from downloadResourceChunked when fetching an image attached to a Feishu message. The library routes image downloads through a chunked helper (instead of the SDK's ~2MiB streaming ceiling) so large screenshots download whole; this error means that chunked download failed (HTTP error, auth, missing message permissions).","triggerScenarios":"p.downloadResourceChunked(ctx, messageID, imageKey, \"image\") returns an error at platform/feishu/feishu.go:3423 — e.g. 404 for an expired/deleted message, 403 without im:message permission, network interruption mid-chunk.","commonSituations":"Trying to download an image from a message older than Feishu's retention or already revoked; bot lacking im:message:readonly scope; token expired mid-download; large image exceeding per-request limits in a chunk.","solutions":["Inspect the wrapped error: 230013 / permission errors require im:message resources scope.","Verify messageID and imageKey come from the same, still-existing message.","Retry on transient network/chunk errors; the chunked helper should be resumable.","Confirm tenant token validity and that the host can reach the Feishu resource endpoints."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if messageID == \"\" || imageKey == \"\" {\n    return errors.New(\"message_id and image_key are required for image download\")\n}","typeGuard":null,"tryCatchPattern":"data, mime, err := p.DownloadImage(ctx, messageID, imageKey)\nif err != nil {\n    if strings.Contains(err.Error(), \"image download\") && isRetryable(err) {\n        // retry chunked download with backoff\n    }\n    return fmt.Errorf(\"cannot fetch image: %w\", err)\n}","preventionTips":["Download images promptly; Feishu message resources can expire or be revoked.","Ensure im:message read scopes are granted for resource fetches.","Use the chunked downloader for images >2MiB rather than the SDK streaming API.","Handle mid-chunk network failures with resumable retries."],"tags":["feishu","download","image","network","permissions"],"backgroundTag":"http-request-failed","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"}