← Back to PRs

#20152: fix(slack): allow app_mention events to bypass dedup cache

by nova-openclaw-cgk open 2026-02-18 15:57 View on GitHub →
channel: slack size: XS
## 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