#21790: fix(msteams): deliver thread replies via continueConversation to survive proxy expiry
channel: msteams
size: S
Cluster:
Fix Microsoft Teams Plugin Issues
## Summary
Closes #18636
When an MS Teams agent runs tool calls that take longer than ~15 s, the Bot Framework `TurnContext` proxy expires. The previous `thread` reply path called `ctx.sendActivity()` directly on the original `TurnContext`, which threw:
```
TypeError: Cannot perform 'set' on a proxy that has been revoked
```
The response was silently lost even though the agent had completed successfully.
## Root cause
`sendMSTeamsMessages` had two separate code paths:
- **thread** — used `ctx.sendActivity()` on the live, expiring `TurnContext`
- **top-level** — used `adapter.continueConversation()` (not affected by proxy expiry)
## Fix
Route **all** replies — both `thread` and `top-level` — through `adapter.continueConversation()`, which opens a fresh Bot Framework turn and is not bound to the original request context.
For `thread`-style replies, `replyToId` is set on each outgoing activity to the `activityId` stored in the conversation reference, so Teams still threads the messages under the original post.
The now-unused `context` parameter is removed from `sendMSTeamsMessages` and callers are updated accordingly.
## Changes
- `extensions/msteams/src/messenger.ts` — unify both reply paths under `continueConversation`; set `replyToId` for thread-style replies; remove unused `context` parameter
- `extensions/msteams/src/reply-dispatcher.ts` — remove `context` from `sendMSTeamsMessages` call
- `extensions/msteams/src/messenger.test.ts` — update thread-reply tests to verify `continueConversation` is called and `replyToId` is set; remove stale `context` arguments
## Test plan
- [x] `pnpm vitest run extensions/msteams/src/` — 144/144 pass
- [x] `pnpm build` — TypeScript + lint + format clean
- [x] Thread-reply test verifies `continueConversation` is called, `activityId` is preserved in the reference, and `replyToId` is set on every activity
- [x] Retry tests (429 throttle, 400 no-retry) updated and passing
- [ ] Manual: send a message that triggers >15 s tool calls and confirm the thread reply arrives
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Unified MS Teams message delivery to use `adapter.continueConversation()` for both thread and top-level replies instead of routing thread replies through the original `TurnContext`. This prevents message loss when the Bot Framework proxy expires after ~15 seconds during long-running tool calls.
**Key changes:**
- Removed the separate thread reply code path that used `ctx.sendActivity()` directly
- Both thread and top-level replies now use `continueConversation()` which opens a fresh Bot Framework turn
- Thread replies preserve threading by setting `replyToId` on each outgoing activity
- Removed the now-unused `context` parameter from `sendMSTeamsMessages()` and updated all callers
- Updated tests to verify `continueConversation` is called and `replyToId` is properly set
The fix correctly addresses the root cause: the original `TurnContext` proxy becomes revoked after the ~15 second timeout, causing "Cannot perform 'set' on a proxy that has been revoked" errors. By using `continueConversation()` for all replies, messages are delivered through a fresh context that isn't bound to the original request lifecycle.
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk
- The implementation is clean, well-tested, and addresses a specific bug with a targeted fix. All tests pass (144/144), the code unifies both reply paths under a single, more robust mechanism, and the change is backwards-compatible. The fix correctly uses Bot Framework's `continueConversation()` API and sets `replyToId` appropriately to preserve threading behavior.
- No files require special attention
<sub>Last reviewed commit: 515fbc4</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#23226: fix(msteams): proactive messaging, EADDRINUSE fix, tool status, ada...
by TarogStar · 2026-02-22
84.4%
#13089: fix(msteams): alias team config under channel conversation IDs for ...
by BradGroux · 2026-02-10
77.2%
#19274: feat(mattermost): enable threaded replies in channels
by rockinyp · 2026-02-17
76.0%
#18716: msteams: fix DM image delivery + user target routing
by ktsushilofficial · 2026-02-17
75.6%
#19213: Telegram: preserve DM topic thread in direct replies
by Kemalau · 2026-02-17
75.6%
#22182: fix(msteams): prevent false auto-restart loop after successful startup
by pandego · 2026-02-20
75.6%
#23320: fix(slack): respect replyToMode when incomingThreadTs is auto-created
by dorukardahan · 2026-02-22
75.3%
#16570: feat(mattermost): add replyToMode threading support
by FBartos · 2026-02-14
75.0%
#22605: fix(msteams): keep provider promise pending until abort to stop aut...
by OpakAlex · 2026-02-21
74.9%
#20406: fix(slack): respect replyToMode when computing statusThreadTs in DMs
by QuinnYates · 2026-02-18
74.7%