#23229: fix(subagent-announce): gate queued delivery on channel deliverability and remove method:send bypass
agents
size: M
experienced-contributor
Cluster:
Agent Messaging Enhancements
## Summary
- **`sendAnnounce` (queued path)**: Added `channelIsDeliverable` guard so channel hints and `deliver:true` are only set when the origin channel is actually registered and routable. Without this, an unroutable channel causes a 15s gateway timeout × 3 retries, then fallback to stale session routes (typically WhatsApp), producing `Error: Delivering to WhatsApp requires target <E.164|group JID>`.
- **`sendSubagentAnnounceDirectly`**: Removed the `method:send` fast path that pushed raw subagent output directly to the user, bypassing the requester agent entirely. All completion announces now go through `method:agent` so the requester agent processes the result and formulates a reply in its own voice. The existing `directOrigin` hints (channel/to/accountId/threadId) on the `method:agent` call are preserved for explicit delivery routing.
## Related
Companion to #23030 (restore `isInternalMessageChannel` guard in `resolveAnnounceOrigin`). Both PRs address subagent announce delivery failures on plugin channels like Gmail.
## Test plan
- [ ] Spawn a subagent from a Gmail thread — completion announce delivers via Gmail, not WhatsApp
- [ ] Spawn a subagent from WhatsApp — completion announce still delivers via WhatsApp (no regression)
- [ ] Spawn a subagent from webchat — completion announce delivers via webchat (internal channel handling unaffected)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
This PR fixes subagent completion announce delivery failures on plugin channels (e.g., Gmail) by adding two defensive guards:
**Change 1 - `sendAnnounce` (queued path):** Added `channelIsDeliverable` check to gate channel delivery hints. Previously, the code only checked `requesterIsSubagent` before setting channel params, which meant unroutable channels (like Gmail when not registered) would still trigger delivery attempts, leading to 15s gateway timeouts × 3 retries, then fallback to stale WhatsApp routes.
**Change 2 - `sendSubagentAnnounceDirectly`:** Removed the `method:send` fast path that pushed raw subagent output directly to users. All completion announces now route through `method:agent` so the requester agent can process results and formulate replies in its own voice, while preserving `directOrigin` hints for explicit routing.
Both changes improve reliability for plugin channels and maintain consistency in the announce delivery flow.
<h3>Confidence Score: 4/5</h3>
- This PR is safe to merge with minor risk - logic changes are well-scoped and defensive
- The changes add defensive guards to prevent delivery failures on unroutable channels and simplify the announce flow by removing the `method:send` bypass. The logic is sound and well-tested (existing tests pass based on test file analysis). However, the first change modifies conditional logic in a subtle way that could affect edge cases not covered by tests.
- No files require special attention - the single changed file has focused, defensive improvements
<sub>Last reviewed commit: aef086a</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#23030: fix(subagents): restore isInternalMessageChannel guard in resolveAn...
by mcinteerj · 2026-02-21
81.0%
#23166: fix(agents): restore subagent announce chain from #22223
by tyler6204 · 2026-02-22
80.0%
#7584: Tests: align subagent announce wait expectations
by justinhuangcode · 2026-02-03
77.5%
#22982: fix: prevent stale threadId from routing subagent announces to wron...
by unboxed-ai · 2026-02-21
77.3%
#22407: fix: allow agent turn after subagent completion message delivery
by noodleprincss-ai · 2026-02-21
77.2%
#22719: fix(agents): make subagent announce timeout configurable (restore 6...
by Valadon · 2026-02-21
76.2%
#23048: feat(session): add `announceDeliver` option to suppress auto-delive...
by nszhsl · 2026-02-21
76.2%
#13303: feat(subagents): replace silent boolean with announce enum ('user'|...
by ivalsaraj · 2026-02-10
74.4%
#20328: fix(agents): Add retry with exponential backoff for subagent announ...
by tiny-ship-it · 2026-02-18
73.6%
#13105: fix: debounce subagent lifecycle events to prevent premature announ...
by mcaxtr · 2026-02-10
73.4%