{"record":{"id":"c4b173b4a969d7ff","repo":"chenhg5/cc-connect","slug":"discord-send-fallback-w","errorCode":null,"errorMessage":"discord: send fallback: %w","messagePattern":"discord: send fallback: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/discord/discord.go","lineNumber":1001,"sourceCode":"\t\tfirst := !ictx.firstDone\n\t\tif first {\n\t\t\tictx.firstDone = true\n\t\t}\n\t\tictx.mu.Unlock()\n\n\t\tvar err error\n\t\tif first {\n\t\t\tc := chunk\n\t\t\t_, err = p.session.InteractionResponseEdit(ictx.interaction, &discordgo.WebhookEdit{Content: &c})\n\t\t} else {\n\t\t\t_, err = p.session.FollowupMessageCreate(ictx.interaction, true, &discordgo.WebhookParams{Content: chunk})\n\t\t}\n\n\t\tif err != nil {\n\t\t\tslog.Warn(\"discord: interaction response failed, falling back to channel message\", \"error\", err)\n\t\t\t_, err = p.session.ChannelMessageSend(ictx.channelID, chunk)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"discord: send fallback: %w\", err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (p *Platform) sendChannelReply(rc replyContext, content string) error {\n\tchunks := core.SplitMessageCodeFenceAware(wrapTablesInCodeBlocks(content), maxDiscordLen)\n\tfor _, chunk := range chunks {\n\t\tvar err error\n\t\tif rc.useThreadChannel() || rc.messageID == \"\" {\n\t\t\t_, err = p.session.ChannelMessageSend(rc.targetChannelID(), chunk)\n\t\t} else {\n\t\t\tref := &discordgo.MessageReference{MessageID: rc.messageID}\n\t\t\t_, err = p.session.ChannelMessageSendReply(rc.channelID, chunk, ref)\n\t\t}\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"discord: send: %w\", err)","sourceCodeStart":983,"sourceCodeEnd":1019,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/discord/discord.go#L983-L1019","documentation":"When responding via the Discord interaction webhook fails, sendInteraction automatically falls back to a plain ChannelMessageSend in the originating channel. This error is thrown only when that fallback ALSO fails, meaning both the interaction response path and the direct channel-send path were rejected. The wrapped error comes from the discordgo ChannelMessageSend call, e.g. HTTP 403 Missing Permissions or 404 Unknown Channel.","triggerScenarios":"The deferred interaction has expired (>15 min) or the webhook token is invalid AND the bot lacks Send Messages permission (or the channel was deleted) so the fallback also returns an error.","commonSituations":"Bot permission was revoked after the interaction started; the user moved/deleted the channel mid-session; Discord API outage affecting both endpoints; replying long after the 15-minute interaction window with the bot not in the channel anymore.","solutions":["Check the wrapped discordgo error's HTTP code: 403 → grant the bot Send Messages/View Channel permission in that channel; 404 → verify the channel still exists","Re-invite the bot with correct permissions or fix role/channel overrides in Discord Server Settings","Check Discord status / retry — if both endpoints failed transiently the next message will likely succeed","Log ictx.channelID and confirm the bot can see that channel (bot must be a member of the guild)"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// before replying, confirm the bot can post to the channel\nhasPerm, _ := p.session.State.UserChannelPermissions(p.botID, ictx.channelID)\nif hasPerm&discordgo.PermissionSendMessages == 0 {\n    return fmt.Errorf(\"bot lacks Send Messages permission in %s\", ictx.channelID)\n}","typeGuard":null,"tryCatchPattern":"var apiErr *discordgo.RESTError\nif errors.As(err, &apiErr) {\n    switch apiErr.Message.Code {\n    case 50001, 50013: // missing access / missing permissions\n        // alert admin to fix bot role permissions\n    }\n}","preventionTips":["Grant the bot Send Messages + View Channel in every channel it serves","Reply within the 15-minute interaction window when possible","Alert admins on repeated fallback failures instead of silently dropping messages","Monitor wrapped discordgo error codes for 403/404"],"tags":["discord","api-error","permissions","fallback"],"backgroundTag":"api-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"}