#21754: slack: pass inbound team_id into stream routing and startStream
channel: slack
size: S
Cluster:
Block Streaming Enhancements
## Summary
This PR fixes Slack channel replies failing with `missing_recipient_team_id` in socket mode by consistently using the inbound event team context for stream routing and stream startup.
## Root Cause
- `dispatch` previously passed only `ctx.teamId` into `startSlackStream` as `recipient_team_id`.
- For Slack channel traffic, the monitor context could be missing or stale while inbound events still carry a reliable `team_id`.
- `chat.startStream` rejects missing `recipient_team_id` for channel replies, causing stream initialization and reply delivery failures.
## Changes
- `src/slack/types.ts`
- Add optional `team_id` to `SlackMessageEvent` and `SlackAppMentionEvent`.
- `src/slack/monitor/message-handler/prepare.ts`
- Prefer `message.team_id` over `ctx.teamId` when resolving the Slack agent route (`resolveAgentRoute`).
- `src/slack/monitor/message-handler/dispatch.ts`
- Add `resolveSlackReplyTeamId({ messageTeamId, ctxTeamId })` helper.
- Pass this resolved team ID into `startSlackStream`.
- `src/slack/monitor/message-handler/prepare.test.ts`
- Add regression test ensuring route resolution uses `message.team_id` when present.
- `src/slack/monitor/message-handler/dispatch.streaming.test.ts`
- Add regression coverage for stream team-id resolution order.
## Validation
- `pnpm test src/slack/monitor/message-handler/prepare.test.ts src/slack/monitor/message-handler/dispatch.streaming.test.ts`
- `pnpm tsgo`
## Behavior
- Channel replies now include required team identity from the inbound event.
- DM behavior is unchanged since it naturally uses `ctx.teamId` fallback when `message.team_id` is absent.
## Confidence Score: 5/5
- Scope is narrow and targeted to Slack stream start/routing.
- Standard fallback behavior is preserved (`message.team_id` -> `ctx.teamId`).
- Automated tests were added specifically for team-id resolution and route precedence.
- No API shape is removed; only optional fields are extended in Slack event typing.
Closes #21734
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
This PR fixes Slack channel replies failing with `missing_recipient_team_id` errors in socket mode by preferring the inbound event's `team_id` over the monitor context's `teamId` when routing messages and initializing streams.
**Changes:**
- Added optional `team_id` field to `SlackMessageEvent` and `SlackAppMentionEvent` type definitions
- Updated route resolution in `prepare.ts` to prefer `message.team_id` over `ctx.teamId` (line 194)
- Added `resolveSlackReplyTeamId` helper function in `dispatch.ts` with clear fallback precedence (`message.team_id` → `ctx.teamId` → `undefined`)
- Passed resolved team ID into `startSlackStream` for reliable stream initialization
- Added regression tests covering both route resolution and stream team ID resolution
**Impact:**
- Channel replies now reliably include team identity from inbound events, preventing stream initialization failures
- DM behavior unchanged (naturally uses `ctx.teamId` fallback when `message.team_id` is absent)
- Standard fallback pattern ensures backwards compatibility
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk - it's a targeted bug fix with proper fallback logic and comprehensive test coverage.
- The fix is narrow in scope, only touching Slack stream initialization and route resolution. The changes follow a clear precedence pattern (`message.team_id` → `ctx.teamId`), preserve existing behavior for DMs, add no breaking changes (only optional fields), and include dedicated regression tests for both affected code paths. The implementation is straightforward and the fallback logic ensures backwards compatibility.
- No files require special attention
<sub>Last reviewed commit: 176b117</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#22096: fix(slack): traverse .original for Slack SDK errors; pass recipient...
by maiclaw · 2026-02-20
86.3%
#21218: fix(slack): pass recipient_team_id and recipient_user_id to chat stre…
by apham0001 · 2026-02-19
86.0%
#20623: fix(slack): duplicate replies and missing streaming recipient params
by rahulsub-be · 2026-02-19
83.1%
#19083: Slack: preserve per-thread context and consistent thread replies
by jkimbo · 2026-02-17
80.7%
#23804: fix(slack): preserve string thread context in queue + DM route
by vincentkoc · 2026-02-22
79.9%
#22485: fix(slack): use threadId from delivery context as threadTs fallback...
by dorukardahan · 2026-02-21
79.3%
#20274: fix: add fallback delivery when stopSlackStream fails
by nova-openclaw-cgk · 2026-02-18
79.2%
#20244: resolution in DM with replyToMode=all
by saurav470 · 2026-02-18
79.0%
#20406: fix(slack): respect replyToMode when computing statusThreadTs in DMs
by QuinnYates · 2026-02-18
78.7%
#22101: fix(slack): dedupe mentions by ts fallback for app_mention
by AIflow-Labs · 2026-02-20
78.3%