Skip to content

MSTeams: Bot replies don't stay in channel threads #15752

@pstabell

Description

@pstabell

Problem

When a user replies in a Teams channel thread, the bot's response creates a new top-level post instead of staying in the same thread. This breaks threaded conversations for project-based workflows.

Environment

  • Clawdbot version: 2026.1.24-3
  • Channel: msteams
  • Conversation type: Channel (not DM or group chat)

Steps to Reproduce

  1. Bot posts a message to a Teams channel (e.g., a project update)
  2. User replies to that message (creating a thread)
  3. Bot responds
  4. Expected: Bot's reply appears in the same thread
  5. Actual: Bot's reply creates a new top-level channel post

Technical Investigation

We investigated the msteams extension code and tried several patches:

Attempt 1: Setting replyToId on the activity

\\ ypescript
// In buildActivity()
if (replyToId) {
activity.replyToId = replyToId;
}
\
Result: No effect - reply still goes to channel root

Attempt 2: Using continueConversation with thread context

\\ ypescript
// Preserve raw conversation ID with ;messageid= suffix
const baseRef = buildConversationReference(params.conversationRef, { preserveThreadContext: true });
const threadRef = { ...baseRef, activityId: threadReplyToId };
await params.adapter.continueConversation(params.appId, threadRef, async (ctx) => {
await ctx.sendActivity(activity);
});
\
Result: No effect

Attempt 3: Including conversation object in activity

\\ ypescript
if (replyToId && conversationRef.rawConversationId) {
activity.conversation = {
id: conversationRef.rawConversationId, // Includes ;messageid=<thread_root>
conversationType: conversationRef.conversation?.conversationType,
};
}
\
Result: No effect

Root Cause Analysis

The issue appears to be in how the Bot Framework SDK handles Teams channel threading:

  1. normalizeMSTeamsConversationId strips the ;messageid=\ suffix from conversation IDs, losing thread context
  2. The
    eplyStyle: 'thread'\ config option doesn't seem to affect channel message threading
  3. Bot Framework's \sendActivity\ doesn't automatically thread based on the incoming message context for channels

Relevant Files

  • \extensions/msteams/src/messenger.ts\ - sendMSTeamsMessages, buildActivity
  • \extensions/msteams/src/inbound.ts\ - normalizeMSTeamsConversationId
  • \extensions/msteams/src/policy.ts\ - resolveMSTeamsReplyPolicy
  • \extensions/msteams/src/monitor-handler/message-handler.ts\ - conversationRef building

Suggested Fix

For Teams channels, replying in a thread requires:

  1. Storing the thread root message ID from incoming \�ctivity.replyToId\
  2. Using the Bot Framework REST API directly: \POST /v3/conversations/{conversationId}/activities/{replyToActivityId}\
  3. Or using Graph API: \POST /teams/{teamId}/channels/{channelId}/messages/{messageId}/replies\

Workaround

Currently using Graph API directly for thread replies as a workaround.

Config

\\yaml
channels:
msteams:
teams:
'59b87350-910c-496a-ab9f-c7aff8438e55':
replyStyle: 'thread'
requireMention: false
channels:
'*':
replyStyle: 'thread'
\\

This config has no effect on channel threading behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    staleMarked as stale due to inactivity

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions