{"record":{"id":"369857c196f3acdb","repo":"chenhg5/cc-connect","slug":"discord-send-image-fallback-w","errorCode":null,"errorMessage":"discord: send image fallback: %w","messagePattern":"discord: send image fallback: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/discord/discord.go","lineNumber":1077,"sourceCode":"\t\trc.mu.Unlock()\n\n\t\tvar err error\n\t\tif first {\n\t\t\t_, err = p.session.InteractionResponseEdit(rc.interaction, &discordgo.WebhookEdit{\n\t\t\t\tFiles: []*discordgo.File{newFile()},\n\t\t\t})\n\t\t} else {\n\t\t\t_, err = p.session.FollowupMessageCreate(rc.interaction, true, &discordgo.WebhookParams{\n\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 image 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 image 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 image: %w\", err)\n\t\t}\n\t\treturn nil\n\tdefault:\n\t\treturn fmt.Errorf(\"discord: SendImage: invalid reply context type %T\", rctx)\n\t}\n}\n\nfunc (p *Platform) SendFile(ctx context.Context, rctx any, file core.FileAttachment) error {\n\tname := file.FileName","sourceCodeStart":1059,"sourceCodeEnd":1095,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/discord/discord.go#L1059-L1095","documentation":"SendImage failed to deliver an image through the Discord interaction webhook AND the automatic fallback to ChannelMessageSendComplex in the originating channel also failed. Both the primary (interaction edit/followup with file attachment) and fallback (channel upload) paths returned errors, so the image was not delivered anywhere.","triggerScenarios":"Interaction expired or webhook token invalid plus the fallback failing due to 403 Missing Permissions, deleted channel, oversized attachment (>8MB for non-nitro guilds), or unsupported content type.","commonSituations":"Replying with images long after the interaction window expired while the bot also lost channel permissions; uploading large screenshots exceeding Discord's 8 MiB (now larger, config-dependent) upload limit; content-type mismatch (e.g. image declared as image/png but actually webp rejected by CDN).","solutions":["Check the wrapped error: 403 → grant bot attach-files/send permission in the channel; 413/size → shrink or compress the image before sending","Verify img.MimeType matches the actual image data and the extension","Check image size against the guild's upload limit and downscale large images","Confirm the channel (ictx.channelID) still exists and the bot remains in the guild"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"const maxUpload = 8 << 20 // 8 MiB default guild limit\nif len(img.Data) > maxUpload {\n    return fmt.Errorf(\"image %s too large for discord upload (%d bytes)\", name, len(img.Data))\n}","typeGuard":null,"tryCatchPattern":"var apiErr *discordgo.RESTError\nif errors.As(err, &apiErr) {\n    switch {\n    case apiErr.Message.Code == 50013: // missing permissions\n        // notify admin\n    case strings.Contains(apiErr.Message.Message, \"too large\"):\n        // compress and retry once\n    }\n}","preventionTips":["Compress/downscale images exceeding the guild upload limit before sending","Set a correct MimeType matching the actual bytes","Keep bot Attach Files permission enabled in served channels","Send images promptly, within the interaction validity window"],"tags":["discord","api-error","permissions","file-upload"],"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"}