{"record":{"id":"fd7ffcc4843d3745","repo":"chenhg5/cc-connect","slug":"download-s-status-d","errorCode":null,"errorMessage":"download %s: status %d","messagePattern":"download (.+?): status (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/discord/discord.go","lineNumber":1527,"sourceCode":"\t\t\t\tslog.Error(\"discord: download file failed\", \"url\", att.URL, \"file_name\", att.Filename, \"error\", err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tfiles = append(files, core.FileAttachment{MimeType: att.ContentType, Data: data, FileName: att.Filename})\n\t\t}\n\t}\n\treturn images, files, audio\n}\n\nconst maxDownloadBytes = 50 << 20 // 50 MiB\n\nfunc downloadURL(u string) ([]byte, error) {\n\tresp, err := core.HTTPClient.Get(u)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"download %s: status %d\", u, resp.StatusCode)\n\t}\n\treturn io.ReadAll(io.LimitReader(resp.Body, maxDownloadBytes+1))\n}\n\n// applyReferencedMessage prepends the replied-to message's author and content\n// to content and prepends any images from the referenced message's attachments.\n// Image attachments (width > 0) are downloaded via download and prepended so the\n// agent sees them before the current message's own images.\nfunc applyReferencedMessage(ref *discordgo.Message, content string, images []core.ImageAttachment, download func(string) ([]byte, error)) (string, []core.ImageAttachment) {\n\tauthor := \"\"\n\tif ref.Author != nil {\n\t\tauthor = ref.Author.Username\n\t}\n\tcontent = \"[replying to \" + author + \": \" + ref.Content + \"]\\n\" + content\n\tfor _, att := range ref.Attachments {\n\t\tif att.Width > 0 && att.Height > 0 {\n\t\t\tdata, err := download(att.URL)\n\t\t\tif err != nil {","sourceCodeStart":1509,"sourceCodeEnd":1545,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/discord/discord.go#L1509-L1545","documentation":"download %s: status %d is thrown when the platform's HTTP file download helper receives a non-200 status code. It fetches attachments/images referenced in messages (e.g. replied-to message attachments) with a size limit. The URL and status code are included so the failing resource is identifiable.","triggerScenarios":"core.HTTPClient.Get succeeded but resp.StatusCode != 200 when downloading an attachment URL (discord.go:1527) — typically 403 (expired CDN signature), 404 (deleted attachment), or 5xx.","commonSituations":"Discord CDN attachment URLs expiring after a short TTL; user deleted the attachment before the bot fetched it; network proxy returning an error page; oversized file capped downstream by maxDownloadBytes.","solutions":["Download the attachment promptly (CDN URLs expire); if 403, re-fetch the message to get a fresh URL","Handle 404 by skipping the attachment gracefully with a user-visible note","Retry 5xx with backoff","Verify proxy/network configuration if all downloads fail"],"exampleFix":"// before\nif resp.StatusCode != http.StatusOK {\n    return nil, fmt.Errorf(\"download %s: status %d\", u, resp.StatusCode)\n}\n// after\nif resp.StatusCode == http.StatusForbidden || resp.StatusCode == http.StatusNotFound {\n    return nil, core.ErrAttachmentUnavailable // caller skips gracefully\n}\nif resp.StatusCode != http.StatusOK {\n    return nil, fmt.Errorf(\"download %s: status %d\", u, resp.StatusCode)\n}","handlingStrategy":"fallback","validationCode":"if u == \"\" { return errors.New(\"empty download URL\") }","typeGuard":null,"tryCatchPattern":"data, err := downloadAttachment(u)\nif err != nil {\n    log.Warn(\"attachment unavailable\", \"url\", u, \"err\", err)\n    return nil, nil // skip attachment gracefully\n}","preventionTips":["Download attachments immediately upon message receipt (CDN URLs expire)","Cap sizes with io.LimitReader as the helper already does","Retry transient 5xx; treat 403/404 as permanent skip"],"tags":["http","download","discord-cdn"],"backgroundTag":"http-error-response","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"}