From 016215911a38702457db258e5d1666d2a9677206 Mon Sep 17 00:00:00 2001 From: Brian Tu Date: Tue, 21 Apr 2026 01:43:21 -0400 Subject: [PATCH] fix(teams): pass channel_info/team_info to lifecycle handler dispatches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The TeamsActivityHandler.on_conversation_update_activity dispatcher was calling on_teams_channel_created/deleted/renamed/restored and on_teams_team_archived/deleted/hardDeleted/renamed/restored/unarchived with only turn_context, but every one of those methods is defined with a 3-arg signature (channel_info, team_info, turn_context) or 2-arg (team_info, turn_context). Result: any Teams team where the bot is installed raises a TypeError the moment a channel is created/renamed/etc., which the default on_turn_error then echoes into the channel as a stack trace — visible to all members. The .NET sibling SDK (microsoft/Agents-for-net, src/libraries/Extensions/Microsoft.Agents.Extensions.Teams/Compat/TeamsActivityHandler.cs:504) is the canonical reference and dispatches with all 3 args (channelData.Channel, channelData.Team, turnContext). The same dispatcher already extracts channel_data.team correctly for on_teams_members_added_dispatch (line 513), so channel_data.channel and channel_data.team are in scope at the call sites — this is purely a transcription bug. No public API changes. --- .../hosting/teams/teams_activity_handler.py | 40 ++++++++++++++----- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/libraries/microsoft-agents-hosting-teams/microsoft_agents/hosting/teams/teams_activity_handler.py b/libraries/microsoft-agents-hosting-teams/microsoft_agents/hosting/teams/teams_activity_handler.py index ba753bb2..8c4fcfa7 100644 --- a/libraries/microsoft-agents-hosting-teams/microsoft_agents/hosting/teams/teams_activity_handler.py +++ b/libraries/microsoft-agents-hosting-teams/microsoft_agents/hosting/teams/teams_activity_handler.py @@ -526,25 +526,45 @@ async def on_conversation_update_activity(self, turn_context: TurnContext): event_type = channel_data.event_type if event_type == "channelCreated": - return await self.on_teams_channel_created(turn_context) + return await self.on_teams_channel_created( + channel_data.channel, channel_data.team, turn_context + ) elif event_type == "channelDeleted": - return await self.on_teams_channel_deleted(turn_context) + return await self.on_teams_channel_deleted( + channel_data.channel, channel_data.team, turn_context + ) elif event_type == "channelRenamed": - return await self.on_teams_channel_renamed(turn_context) + return await self.on_teams_channel_renamed( + channel_data.channel, channel_data.team, turn_context + ) elif event_type == "teamArchived": - return await self.on_teams_team_archived(turn_context) + return await self.on_teams_team_archived( + channel_data.team, turn_context + ) elif event_type == "teamDeleted": - return await self.on_teams_team_deleted(turn_context) + return await self.on_teams_team_deleted( + channel_data.team, turn_context + ) elif event_type == "teamHardDeleted": - return await self.on_teams_team_hard_deleted(turn_context) + return await self.on_teams_team_hard_deleted( + channel_data.team, turn_context + ) elif event_type == "channelRestored": - return await self.on_teams_channel_restored(turn_context) + return await self.on_teams_channel_restored( + channel_data.channel, channel_data.team, turn_context + ) elif event_type == "teamRenamed": - return await self.on_teams_team_renamed(turn_context) + return await self.on_teams_team_renamed( + channel_data.team, turn_context + ) elif event_type == "teamRestored": - return await self.on_teams_team_restored(turn_context) + return await self.on_teams_team_restored( + channel_data.team, turn_context + ) elif event_type == "teamUnarchived": - return await self.on_teams_team_unarchived(turn_context) + return await self.on_teams_team_unarchived( + channel_data.team, turn_context + ) return await super().on_conversation_update_activity(turn_context)