{"record":{"id":"f0836577d0a6aa82","repo":"chenhg5/cc-connect","slug":"fetch-bot-member-w","errorCode":null,"errorMessage":"fetch bot member: %w","messagePattern":"fetch bot member: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/discord/discord.go","lineNumber":1442,"sourceCode":"func (p *Platform) cacheBotRoleIDForGuild(s *discordgo.Session, guildID string, guildRoles []*discordgo.Role) {\n\tif s == nil || guildID == \"\" || p.botID == \"\" {\n\t\treturn\n\t}\n\troleID, err := p.resolveBotRoleIDForGuild(s, guildID, guildRoles)\n\tif err != nil {\n\t\tslog.Debug(\"discord: resolve bot managed role failed\", \"guild\", guildID, \"error\", err)\n\t\treturn\n\t}\n\tif roleID == \"\" {\n\t\treturn\n\t}\n\tp.botRoleIDs.Store(guildID, roleID)\n}\n\nfunc (p *Platform) resolveBotRoleIDForGuild(s *discordgo.Session, guildID string, guildRoles []*discordgo.Role) (string, error) {\n\tmember, err := s.GuildMember(guildID, p.botID)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"fetch bot member: %w\", err)\n\t}\n\tif member == nil || len(member.Roles) == 0 {\n\t\treturn \"\", nil\n\t}\n\n\tmemberRoleSet := make(map[string]struct{}, len(member.Roles))\n\tfor _, roleID := range member.Roles {\n\t\tmemberRoleSet[roleID] = struct{}{}\n\t}\n\n\troles := guildRoles\n\tif len(roles) == 0 {\n\t\troles, err = s.GuildRoles(guildID)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"fetch guild roles: %w\", err)\n\t\t}\n\t}\n","sourceCodeStart":1424,"sourceCodeEnd":1460,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/discord/discord.go#L1424-L1460","documentation":"fetch bot member wraps an error from discordgo's GuildMember call when resolving the bot's own member record (needed to compute its highest role) fails. Used to determine whether the bot can mention/interact with roles in a guild. The error is wrapped with context and returned to the caller.","triggerScenarios":"Calling resolveBotRoleIDForGuild (discord.go:1442) when the bot token is invalid, the bot is not a member of the guild, the guildID is wrong, or the API is unreachable / rate limited.","commonSituations":"Bot kicked from the guild but config still references it; wrong guild ID in config.toml; expired or rotated bot token; Discord outage or 429.","solutions":["Verify the bot is actually a member of the configured guild","Check the guild ID in config.toml matches the target server","Re-generate the bot token and restart","Retry on 429/5xx; check Discord status page"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if p.botID == \"\" || guildID == \"\" { return errors.New(\"bot ID / guild ID required before resolving role\") }","typeGuard":null,"tryCatchPattern":"member, err := s.GuildMember(guildID, p.botID)\nif err != nil {\n    if shouldRetry(err) { time.Sleep(backoff); retry() }\n    return fmt.Errorf(\"fetch bot member: %w\", err)\n}","preventionTips":["Verify bot membership in guild during startup health checks","Validate guild ID in config at boot","Handle token rotation with re-auth hooks"],"tags":["discord","api","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-14T00:17:10.932Z"}