← Back to PRs

#23804: fix(slack): preserve string thread context in queue + DM route

by vincentkoc open 2026-02-22 18:09 View on GitHub →
channel: slack maintainer size: XS dedupe:parent
## Summary - rebases the `#11934` Slack queue thread-context fix on latest `main` - preserves string Slack `thread_ts` during collect-mode queue grouping (`queue/drain.ts`) - keeps DM `deliveryContext.threadId` updates in Slack prepare/dispatch route persistence - adds an Unreleased changelog fix line ## Linked Issue/PR - Related #10837 - Supersedes #11934 ## Verification - `pnpm test src/auto-reply/reply/reply-flow.test.ts` - test passes locally ## Scope boundary - does not include broader `replyToMode: off` threading behavior changes (handled in #23799) <!-- greptile_comment --> <h3>Greptile Summary</h3> This PR fixes Slack thread context being lost during collect-mode queue draining and DM route persistence, preventing threaded follow-up messages from leaking to the main channel. - **Queue drain thread grouping (`drain.ts`)**: Adds empty-string guards to `originatingThreadId` checks so that empty-string Slack `thread_ts` values are treated the same as `null`/`undefined`, preventing them from producing distinct routing keys that split same-thread messages into different delivery batches. Also fixes a stale debug comment pointing to a renamed test file. - **DM route persistence (`prepare.ts`)**: Adds `threadId: threadContext.messageThreadId` to the `updateLastRoute` call in `recordInboundSession`, so Slack DM sessions record thread context during inbound message preparation — matching the pattern already used by Telegram and other channels. - **Dispatch route persistence (`dispatch.ts`)**: Adds `threadId: prepared.ctxPayload.MessageThreadId` to the `deliveryContext` in the dispatch-time `updateLastRoute` call, ensuring thread context survives through the full prepare→dispatch lifecycle. - **Changelog**: Adds an Unreleased fix entry referencing #11934. <h3>Confidence Score: 5/5</h3> - This PR is safe to merge — it adds defensive guards and missing field propagation without changing existing control flow. - All changes are additive/defensive: empty-string guards on existing null checks, and adding a missing `threadId` field to two `updateLastRoute` call sites. The types (`DeliveryContext.threadId: string | number`, `FollowupRun.originatingThreadId: string | number`) already support the values being passed. The fix follows established patterns used by other channels (Telegram). No existing behavior is altered for non-empty thread IDs. - No files require special attention <sub>Last reviewed commit: 0b2d845</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs