{"record":{"id":"f6c9026acfcf62ab","repo":"chenhg5/cc-connect","slug":"discord-send-channel-buttons-w","errorCode":null,"errorMessage":"discord: send channel buttons: %w","messagePattern":"discord: send channel buttons: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/discord/discord.go","lineNumber":1206,"sourceCode":"\tcase *interactionReplyCtx:\n\t\tif err := p.sendInteraction(rc, content); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err := p.session.FollowupMessageCreate(rc.interaction, true, &discordgo.WebhookParams{\n\t\t\tContent:    content,\n\t\t\tComponents: components,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"discord: send button followup: %w\", err)\n\t\t}\n\t\treturn nil\n\tcase replyContext:\n\t\t_, err := p.session.ChannelMessageSendComplex(rc.targetChannelID(), &discordgo.MessageSend{\n\t\t\tContent:    content,\n\t\t\tComponents: components,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"discord: send channel buttons: %w\", err)\n\t\t}\n\t\treturn nil\n\tdefault:\n\t\treturn core.ErrNotSupported\n\t}\n}\n\nfunc (p *progressPlatform) ProgressUpdateInterval() time.Duration {\n\treturn 2 * time.Second\n}\n\nvar _ core.ImageSender = (*Platform)(nil)\nvar _ core.FileSender = (*Platform)(nil)\nvar _ core.InlineButtonSender = (*Platform)(nil)\nvar _ core.ProgressStyleProvider = (*progressPlatform)(nil)\nvar _ core.ProgressCardPayloadSupport = (*progressPlatform)(nil)\nvar _ core.ProgressUpdateThrottler = (*progressPlatform)(nil)\n","sourceCodeStart":1188,"sourceCodeEnd":1224,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/discord/discord.go#L1188-L1224","documentation":"For a plain replyContext, SendWithButtons posts the content plus component rows via ChannelMessageSendComplex; this error wraps that request's failure. It means Discord rejected or failed the button message send, not that buttons were missing. The wrapped error carries the Discord API code and message.","triggerScenarios":"ChannelMessageSendComplex fails when sending components — missing SEND_MESSAGES/VIEW_CHANNEL permission, invalid component payload, non-existent channel ID, or API/network failure.","commonSituations":"Bot permissions changed in the channel; channel deleted or thread archived; stale channel ID reconstructed from an old session key; Discord API incident.","solutions":["Read the wrapped Discord error code (50001/50013 = access/permission, 10003 = unknown channel) and fix accordingly","Restore bot messaging permissions in the target channel","Verify the channel/thread ID still exists and the thread is not archived or locked","Retry with backoff on 5xx/rate-limit (429) responses"],"exampleFix":"// before: no retry\n_, err := p.session.ChannelMessageSendComplex(chID, msg)\n// after\n_, err := p.session.ChannelMessageSendComplex(chID, msg)\nif isRateLimited(err) { time.Sleep(backoff); retry() }","handlingStrategy":"retry","validationCode":"perms, err := p.session.ChannelPermissions(channelID, botUserID)\nif err != nil || perms&discordgo.PermissionSendMessages == 0 {\n    return errors.New(\"bot cannot send messages in target channel\")\n}","typeGuard":null,"tryCatchPattern":"err := p.SendWithButtons(ctx, rctx, content, buttons)\nif isRetryable(err) { // 429 or 5xx\n    time.Sleep(backoff)\n    err = p.SendWithButtons(ctx, rctx, content, buttons)\n}\nreturn err","preventionTips":["Verify SEND_MESSAGES/VIEW_CHANNEL permissions for the bot role","Re-resolve channel/thread IDs from fresh sessions rather than stale keys","Handle 429 rate limits with backoff and respect Retry-After","Archive/lock state checks before posting into threads"],"tags":["discord","buttons","channel-message","api-error","permissions"],"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"}