#20152: fix(slack): allow app_mention events to bypass dedup cache
channel: slack
size: XS
Cluster:
Slack Thread Management Improvements
## Summary
- **Exempts `app_mention` events from the message dedup cache** in `createSlackMessageHandler`. Slack delivers both `message` and `app_mention` for the same @mention with no ordering guarantee. The shared `channelId:ts` dedup key causes the second event to be silently dropped ~50% of the time.
- When `message` wins the race in a `requireMention: true` channel, it's dropped for lacking a mention but the dedup key is still set. The `app_mention` (with `wasMentioned: true`) is then deduped, causing missed mentions and lost thread context (`invalid_thread_ts` → fallback to main channel).
- The fix is safe because the downstream `createInboundDebouncer` already handles dedup at the flush level via `buildKey`, and `prepareSlackMessage` correctly merges `wasMentioned` across debounced entries.
## Test plan
- [ ] Verify existing `vitest` tests pass (`src/slack/monitor/message-handler/prepare.test.ts`, `src/slack/monitor/monitor.test.ts`)
- [ ] In a channel with `requireMention: true`, @mention the bot — confirm it responds every time (not ~50%)
- [ ] @mention the bot in a thread reply — confirm response stays in the thread (no `invalid_thread_ts` fallback)
- [ ] Send a message without @mention in a `requireMention: true` channel — confirm bot still ignores it
- [ ] Confirm no double-processing: bot should respond once per @mention, not twice
Fixes #20151
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
This PR fixes a race condition where Slack's `app_mention` events were being silently dropped ~50% of the time due to a shared dedup cache key (`channelId:ts`) with `message` events. In `requireMention: true` channels, if the `message` event won the race it would set the dedup key (but be dropped for lacking a mention), causing the subsequent `app_mention` to be deduped — resulting in missed mentions and `invalid_thread_ts` errors.
The fix exempts `app_mention` events from the `markMessageSeen` dedup check entirely, relying on the downstream `createInboundDebouncer` to handle dedup at the flush level.
- The fix correctly solves the core issue for `requireMention: true` channels
- There is a potential double-processing concern: when `debounceMs` is 0 (the default), both `message` and `app_mention` events will independently reach dispatch in channels where `requireMention` is `false`, since the debouncer does not buffer at zero debounce
- A safer approach would be to still call `markMessageSeen` for `app_mention` events (to poison the key for the competing `message` event) while skipping the early-return, reducing the double-processing window
<h3>Confidence Score: 3/5</h3>
- The fix addresses the critical missed-mention bug but may introduce double-processing in non-requireMention channels with default (zero) debounce.
- The change correctly fixes the described race condition for requireMention channels, which is the primary use case. However, the complete bypass of markMessageSeen for app_mention events (neither checking nor setting the key) means both message and app_mention can independently reach dispatch when debounceMs is 0 (the default). This could cause duplicate bot responses in channels where requireMention is false.
- src/slack/monitor/message-handler.ts — the dedup bypass logic at line 119 needs attention for the double-processing edge case.
<sub>Last reviewed commit: 78d7065</sub>
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#7719: fix(slack): thread replies with @mentions dropped in requireMention...
by SocialNerd42069 · 2026-02-03
92.4%
#22101: fix(slack): dedupe mentions by ts fallback for app_mention
by AIflow-Labs · 2026-02-20
86.5%
#21108: slack: keep requireMention thread follow-ups when thread session is...
by JayElRay · 2026-02-19
81.8%
#20479: fix(slack): keep replies flowing for oversized file uploads
by olyashok · 2026-02-19
80.1%
#19419: feat(slack): track thread participation for implicit mentions
by Utkarshbhimte · 2026-02-17
78.3%
#20406: fix(slack): respect replyToMode when computing statusThreadTs in DMs
by QuinnYates · 2026-02-18
77.7%
#23320: fix(slack): respect replyToMode when incomingThreadTs is auto-created
by dorukardahan · 2026-02-22
77.4%
#22433: Slack: fix thread context loss after session reset
by stgarrity · 2026-02-21
77.1%
#16105: fix: handle message_reaction updates in group polling mode
by claw-sylphx · 2026-02-14
76.7%
#19435: fix(slack): properly handle group DM (MPIM) events
by Utkarshbhimte · 2026-02-17
76.6%