fix(gateway): reject delivery to unconfigured plugin channels in agent handler#2718
Merged
alexey-pelykh merged 1 commit intoJun 15, 2026
Merged
Conversation
…t handler When a session's lastChannel points to a plugin channel (e.g. msteams) with no configured accounts, the agent handler silently accepted the delivery request. isDeliverableMessageChannel() only checks plugin-registry presence, not configured accounts, and listConfiguredMessageChannels() was consulted only on the INTERNAL_MESSAGE_CHANNEL fallback path — never for an explicitly-resolved plugin channel. Now, before internal-channel resolution, a wanted delivery to a registered plugin channel (not a built-in CHANNEL_IDS channel, not internal) with no configured accounts falls back to INTERNAL_MESSAGE_CHANNEL so channel-selection surfaces a proper "Channel is required" error. Built-in channels skip the check. Adds a gateway test for the unconfigured-plugin fallback and updates the existing "reuses last plugin route" test to register a configured plugin (it previously asserted delivery succeeded with an unconfigured plugin — encoding the bug). createMSTeamsPlugin gains an optional accountIds param. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
alexey-pelykh
enabled auto-merge (squash)
June 15, 2026 14:06
alexey-pelykh
deleted the
fix/reject-unconfigured-plugin-channel-delivery
branch
June 15, 2026 14:12
This was referenced Jun 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When an agent run requests delivery (
deliver: true) and the resolved channel is a plugin channel with no configured accounts (e.g.msteamsregistered but no accounts set up), the agent handler silently accepted the delivery request.isDeliverableMessageChannel()only checks plugin-registry presence, not whether the plugin has configured accounts, and the configured-accounts check (listConfiguredMessageChannels()) was consulted only on theINTERNAL_MESSAGE_CHANNELfallback path — never for an explicitly-resolved plugin channel. The run was then dispatched to an unusable channel instead of surfacing a proper error.Fix
src/gateway/server-methods/agent.ts: before internal-channel resolution, if delivery is wanted and the resolved channel is a registered plugin channel (not a built-inCHANNEL_IDSchannel, not internal) that has no configured accounts, fall back toINTERNAL_MESSAGE_CHANNEL. The existing channel-selection logic then surfaces the proper "Channel is required" error instead of dispatching to an unusable channel. Built-in channels skip the check (always considered available).Tests
src/gateway/server.agent.gateway-server-agent-b.test.ts:res.ok === false,INVALID_REQUEST, and that no agent dispatch occurs.accountIds: ["default"]). It previously registered an unconfigured plugin yet asserted delivery succeeded — i.e. it encoded the bug.createMSTeamsPlugingains an optionalaccountIdsparameter to express configured vs. unconfigured.pnpm check(format +tsgotypecheck + lint + fork guards) passes.🤖 Generated with Claude Code