{"record":{"id":"0c5b46029827fdea","repo":"chenhg5/cc-connect","slug":"discord-send-file-w","errorCode":null,"errorMessage":"discord: send file: %w","messagePattern":"discord: send file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/discord/discord.go","lineNumber":1142,"sourceCode":"\t\t\t\tFiles: []*discordgo.File{newFile()},\n\t\t\t})\n\t\t}\n\t\tif err != nil {\n\t\t\tslog.Warn(\"discord: interaction file failed, falling back to channel message\", \"error\", err)\n\t\t\t_, err = p.session.ChannelMessageSendComplex(rc.channelID, &discordgo.MessageSend{\n\t\t\t\tFiles: []*discordgo.File{newFile()},\n\t\t\t})\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"discord: send file fallback: %w\", err)\n\t\t\t}\n\t\t}\n\t\treturn nil\n\tcase replyContext:\n\t\t_, err := p.session.ChannelMessageSendComplex(rc.targetChannelID(), &discordgo.MessageSend{\n\t\t\tFiles: []*discordgo.File{newFile()},\n\t\t})\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"discord: send file: %w\", err)\n\t\t}\n\t\treturn nil\n\tdefault:\n\t\treturn fmt.Errorf(\"discord: SendFile: invalid reply context type %T\", rctx)\n\t}\n}\n\nfunc buildDiscordActionRows(rows [][]core.ButtonOption) []discordgo.MessageComponent {\n\tcomponents := make([]discordgo.MessageComponent, 0, len(rows))\n\tfor _, row := range rows {\n\t\tif len(row) == 0 {\n\t\t\tcontinue\n\t\t}\n\t\tbuttons := make([]discordgo.MessageComponent, 0, len(row))\n\t\tfor idx, btn := range row {\n\t\t\tstyle := discordgo.SecondaryButton\n\t\t\tswitch idx {\n\t\t\tcase 0:","sourceCodeStart":1124,"sourceCodeEnd":1160,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/discord/discord.go#L1124-L1160","documentation":"This error wraps a failure from discordgo's ChannelMessageSendComplex when the platform tries to upload a file to a regular (non-interaction) Discord channel during SendFile. The library throws it whenever the Discord REST API rejects or fails the multipart file-upload request for a plain replyContext. It is a wrapper, so the root cause (permissions, size limits, network) is in the wrapped error.","triggerScenarios":"Platform.SendFile is called with a replyContext and ChannelMessageSendComplex fails — e.g. the bot lacks ATTACH_FILES/SEND_MESSAGES permission in the channel, the file exceeds Discord's 8MB/25MB upload limit, or the HTTP request fails.","commonSituations":"Bot role missing attach-files permission after channel settings change; sending generated files larger than the guild's upload cap; expired/invalid bot token causing 401; transient Discord API 5xx or network outage.","solutions":["Inspect the wrapped error for the Discord API code (e.g. 50013 missing permissions, 40005 payload too large) and fix that cause","Grant the bot ATTACH_FILES and VIEW_CHANNEL/SEND_MESSAGES permissions in the target channel","Compress or split files so they fit under the guild's upload limit","Verify the bot token is valid and the Discord gateway/API is reachable","Retry on transient 5xx/network errors with backoff"],"exampleFix":"// before: failing on oversized file\nerr := p.SendFile(ctx, rctx, filePath)\n// after: check size first\nif fi.Size() > 25<<20 { return fmt.Errorf(\"file exceeds Discord upload limit\") }\nreturn p.SendFile(ctx, rctx, filePath)","handlingStrategy":"try-catch","validationCode":"if fi, err := os.Stat(filePath); err != nil || fi.Size() > 25<<20 {\n    return fmt.Errorf(\"file missing or too large for Discord: %v\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := p.SendFile(ctx, rctx, path); err != nil {\n    var restErr *discordgo.RESTError\n    if errors.As(err, &restErr) {\n        log.Printf(\"discord file send failed: code=%d msg=%s\", restErr.Message.Code, restErr.Message.Message)\n    }\n    return fmt.Errorf(\"send file: %w\", err)\n}","preventionTips":["Check bot ATTACH_FILES and SEND_MESSAGES permissions before sending","Enforce a file-size cap below the guild upload limit (8MB default, 25MB boosted)","Verify token validity at startup (cc-connect doctor style checks)","Retry transient 5xx/429 errors with exponential backoff"],"tags":["discord","file-upload","discordgo","api-error"],"backgroundTag":"api-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"}