{"record":{"id":"39a4c06b877d1b6a","repo":"chenhg5/cc-connect","slug":"slack-resolve-channel-name-for-s-w","errorCode":null,"errorMessage":"slack: resolve channel name for %s: %w","messagePattern":"slack: resolve channel name for (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/slack/slack.go","lineNumber":649,"sourceCode":"\tif err != nil || name == \"\" {\n\t\treturn channelID\n\t}\n\treturn name\n}\n\nfunc (p *Platform) ResolveChannelName(channelID string) (string, error) {\n\tp.channelCacheMu.RLock()\n\tif name, ok := p.channelNameCache[channelID]; ok {\n\t\tp.channelCacheMu.RUnlock()\n\t\treturn name, nil\n\t}\n\tp.channelCacheMu.RUnlock()\n\n\tinfo, err := p.client.GetConversationInfo(&slack.GetConversationInfoInput{\n\t\tChannelID: channelID,\n\t})\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"slack: resolve channel name for %s: %w\", channelID, err)\n\t}\n\n\tp.channelCacheMu.Lock()\n\tp.channelNameCache[channelID] = info.Name\n\tp.channelCacheMu.Unlock()\n\n\treturn info.Name, nil\n}\n\n// FormattingInstructions returns Slack mrkdwn formatting guidance for the agent.\nfunc (p *Platform) FormattingInstructions() string {\n\treturn `You are responding in Slack. Use Slack's mrkdwn format, NOT standard Markdown:\n- Bold: *text* (single asterisks, not double)\n- Italic: _text_\n- Strikethrough: ~text~\n- Code: ` + \"`text`\" + `\n- Code block: ` + \"```text```\" + `\n- Blockquote: > text","sourceCodeStart":631,"sourceCodeEnd":667,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/slack/slack.go#L631-L667","documentation":"ResolveChannelName maps a Slack channel ID to its human-readable name via client.GetConversationInfo. This error wraps any failure from that API call — invalid or unknown channel ID, missing scope, rate limit, or network error — and includes the channel ID for context.","triggerScenarios":"GetConversationInfo returns an error: channel ID no longer exists (channel deleted/archived), bot is not a member and lacks the scope, Slack rate limit hit, or network/API failure.","commonSituations":"Bot token missing groups:read/channels:read scope; messaging a channel the bot was removed from; stale channel ID stored in an old session after the channel was deleted; Slack 429 rate limiting under heavy traffic.","solutions":["Verify the channel ID exists and the bot can see it (try conversations.list with the same token)","Add the required scope (channels:read for public, groups:read for private) and reinstall the app","Check whether the error wraps a rate-limit (rate_limited) and retry with backoff","Invite the bot to the channel or use a channel ID from a fresh session"],"exampleFix":"// before\n// token lacks channels:read, GetConversationInfo fails\n// after\n// In Slack app settings: OAuth & Permissions -> add channels:read / groups:read, reinstall app","handlingStrategy":"try-catch","validationCode":"// pre-flight: can this token resolve channels at all?\n_, err := p.client.GetConversations(&slack.GetConversationsParameters{Limit: 1})","typeGuard":null,"tryCatchPattern":"name, err := p.ResolveChannelName(channelID)\nvar rl *slack.RateLimitedError\nif errors.As(err, &rl) { time.Sleep(rl.RetryAfter); name, err = p.ResolveChannelName(channelID) }\nif err != nil { name = channelID /* fallback to raw ID */ }","preventionTips":["Grant channels:read and groups:read scopes at install time","Cache resolved channel names (the adapter already does) to limit API calls","Fall back to displaying the raw channel ID on failure","Re-add the bot after it is removed from channels"],"tags":["slack","api","channel","scope"],"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-14T00:17:10.932Z"}