#12204: fix(discord): resolve numeric guildId/channelId pairs in channel allowlist
channel: discord
size: M
trusted-contributor
experienced-contributor
Cluster:
Discord and MS Teams Fixes
Fixes #12185
## Summary
When users configure Discord channel allowlists with numeric `guildId/channelId` pairs (e.g. `111222333/444555666`), `parseDiscordChannelInput` treated the channel part as a channel *name* rather than an ID. This caused the resolution to attempt a name-based lookup against guild channels, which always failed for numeric IDs, silently dropping inbound messages from those channels.
### Changes
- **Numeric channel ID detection**: when both halves of `guild/channel` are all-digits, parse the channel part as `channelId` for direct API lookup
- **Guild membership validation**: reject entries where the fetched channel belongs to a different guild than specified
- **Graceful error handling**: catch 404/403 from channel lookups so one bad entry doesn't abort the entire batch
- **Guild context preservation**: include `guildId` on unresolved results so downstream onboarding doesn't default to wildcard guild
- **Name fallback**: when a numeric channel ID lookup fails and a guild was specified, fall back to name matching within that guild (supports channels with numeric names like "2024")
### Test plan
- [x] `"111222333/444555666"` resolves via direct channel ID lookup (TDD — test written first)
- [x] `"111222333/444555666"` where channel belongs to different guild → `resolved: false` with note
- [x] `"111222333/999000111"` where channel ID is 404 → marks unresolved, doesn't abort batch, preserves `guildId`
- [x] `"111222333/777888999"` where channel ID is 403 → marks unresolved, doesn't abort batch
- [x] `"111222333/2024"` where "2024" is a channel name → falls back to name matching within guild
- [x] All 7 new tests fail before fix, pass after
- [x] All 12 existing discord test files pass (40+ tests)
- [x] `pnpm build && pnpm check` clean
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR updates Discord allowlist parsing/resolution to correctly handle numeric `guildId/channelId` inputs by treating the channel segment as an ID (with optional guild-scoped name fallback on 404), adds a guild-membership consistency check for resolved channels, and improves channel fetch error classification (403 vs 404 vs invalid payload) so a single bad entry doesn’t abort batch resolution.
The main logic lives in `src/discord/resolve-channels.ts`, where `parseDiscordChannelInput` now returns `{guildId, channelId}` when both segments are all-digits, and `fetchChannel` now returns a discriminated `FetchChannelResult` to avoid conflating forbidden/not-found/invalid responses. `src/discord/resolve-channels.test.ts` adds coverage for the numeric-pair path, guild mismatch rejection, 404/403 behavior, and malformed payload handling.
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk.
- The changes are localized to Discord allowlist parsing/resolution, add targeted tests for the new numeric `guildId/channelId` path, and the new error classification avoids previously reported incorrect fallbacks. I did not find any additional deterministic logic issues in the diff beyond previously addressed threads.
- No files require special attention
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#8648: fix: don't treat bare numeric Discord IDs as definitive target IDs
by dbottme · 2026-02-04
84.0%
#22557: fix(discord): coerce exec approval approver IDs to string to preven...
by zwffff · 2026-02-21
84.0%
#21463: fix(discord): prevent WebSocket death spiral + fix numeric channel ID…
by akropp · 2026-02-20
83.9%
#16720: fix: fall back to guild_id when guild object is missing in resolveD...
by xqliu · 2026-02-15
82.9%
#17513: fix(discord): respect groupPolicy in channel config fallback (#4555)
by aronchick · 2026-02-15
82.4%
#23158: discord: harden preflight/reply path against slow lookup latency
by danielstarman · 2026-02-22
80.2%
#17648: fix: Discord guild channel detection using rawMessage.guild_id
by MisterGuy420 · 2026-02-16
79.8%
#22524: fix(doctor): preserve precision of large Discord snowflake IDs in -...
by jmasson · 2026-02-21
78.4%
#16828: fix(config): transform Discord user/role IDs to strings
by Limitless2023 · 2026-02-15
78.3%
#19615: fix(discord): include default account when sub-accounts are configured
by prue-starfield · 2026-02-18
77.2%