[Bug]: Sub-agent completion announce fails with "unsupported channel: telegram"
Summary
Sub-agent completion announcements fail silently when spawned from Telegram sessions. The Gateway attempts direct delivery 3 times, each failing with unsupported channel: telegram, then gives up. The requester never receives notification that the sub-agent completed.
This affects all sub-agents spawned from Telegram (both DMs and groups) using sessions_spawn.
Environment
- OpenClaw version: 2026.2.17+ (confirmed on 2026.2.17)
- OS: Linux 6.8.0-90-generic (x64)
- Node: v22.22.0
- Channel: Telegram (affects both DMs and groups)
- Spawn method:
sessions_spawn tool
Steps to Reproduce
- Configure OpenClaw with Telegram channel
- From a Telegram session (DM or group), spawn a sub-agent:
sessions_spawn(task="Create a report on XYZ", model="sonnet")
- Wait for the sub-agent to complete its task
- Check Gateway logs:
journalctl --user -u openclaw-gateway -f
Expected Behavior
- Sub-agent completes successfully
- OpenClaw announces the completion back to the Telegram session
- User receives the sub-agent's result
Actual Behavior
- Sub-agent completes successfully ✅
- OpenClaw attempts to announce the completion via "direct announce" mechanism
- Each attempt fails with:
Subagent completion direct announce failed for run <id>: unsupported channel: telegram
- After 3 retries, OpenClaw gives up and marks cleanup as complete
- User never receives the notification ❌
Evidence
Gateway Logs
Feb 20 14:46:51 srv1304246 node[2097444]: 2026-02-20T14:46:51.851+00:00 Subagent completion direct announce failed for run 1495559a-7e44-465a-b24f-bd5d595fc4b4: unsupported channel: telegram
Feb 20 14:46:52 srv1304246 node[2097444]: 2026-02-20T14:46:52.904+00:00 Subagent completion direct announce failed for run 1495559a-7e44-465a-b24f-bd5d595fc4b4: unsupported channel: telegram
Feb 20 14:46:54 srv1304246 node[2097444]: 2026-02-20T14:46:54.940+00:00 Subagent completion direct announce failed for run 1495559a-7e44-465a-b24f-bd5d595fc4b4: unsupported channel: telegram
Feb 20 14:46:54 srv1304246 node[2097444]: 2026-02-20T14:46:54.942+00:00 [warn] Subagent announce give up (retry-limit) run=1495559a-7e44-465a-b24f-bd5d595fc4b4 child=agent:main:subagent:2455ac6a-4e01-4f48-80dd-65752c0c01a2 requester=agent:main:main retries=3 endedAgo=3s
Subagent Run Metadata
From /home/openclaw/.openclaw/subagents/runs.json:
{
"runId": "1495559a-7e44-465a-b24f-bd5d595fc4b4",
"requesterSessionKey": "agent:main:main",
"requesterOrigin": {
"channel": "telegram",
"to": "telegram:8517717047",
"accountId": "default"
},
"expectsCompletionMessage": true,
"outcome": { "status": "ok" },
"announceRetryCount": 3, ← Tried 3 times
"lastAnnounceRetryAt": 1771598814941,
"cleanupCompletedAt": 1771598814941
}
Root Cause Analysis
Looking at src/agents/subagent-announce.ts, the sendSubagentAnnounceDirectly() function uses two delivery paths:
- For completion messages (
expectsCompletionMessage=true): Uses callGateway({ method: "send", ... })
- For trigger messages: Uses
callGateway({ method: "agent", ... })
The send method path (used for completion messages) calls src/gateway/server-methods/send.ts, which:
- Normalizes the channel via
normalizeChannelId(channelInput)
- Calls
getChannelPlugin(channel) to fetch the plugin
- If plugin is
null, returns unsupported channel: <channel>
The bug: When getChannelPlugin() is called during sub-agent announce, Telegram plugin may not be fully initialized at the Gateway level, causing it to return null even though Telegram is configured and working.
The agent method path works fine because it routes through the standard agent execution pipeline, which properly resolves channels regardless of plugin initialization state.
Impact
- Severity: High — breaks core sub-agent workflow for Telegram users
- Scope: All sub-agents spawned from Telegram sessions
- User experience: Silent failure — users think sub-agents are "sleeping" when they've actually finished
- Workarounds: None (users must manually check session history or poll
subagents list)
Affected Channels
Based on code inspection, this likely affects:
Channels that likely work fine:
- IRC, Signal, Google Chat (if they use
agent method fallback)
Proposed Solution
Option 1: Always use agent method for direct delivery (simplest, most consistent)
Change sendSubagentAnnounceDirectly() to always use callGateway({ method: "agent", ... }) instead of conditionally using send. The agent method handles all deliverable channels correctly.
Option 2: Fix channel plugin initialization race
Ensure getChannelPlugin() always returns the correct plugin during sub-agent announce, even if called before full Gateway initialization.
Option 3: Retry with agent method on send failure
If send fails with "unsupported channel", fallback to agent method automatically.
Recommendation: Option 1 — simplest, most consistent, eliminates the race condition entirely.
Related Issues
Additional Context
This bug was discovered when investigating why sub-agents consistently complete successfully but users never receive notifications. The sub-agent runs are logged in subagents/runs.json with status: "ok" and announceRetryCount: 3, confirming the completion succeeded but delivery failed.
The issue is specific to the direct announce delivery path and does not affect queued announces (which use a different code path through enqueueAnnounce).
Reproducible: Yes (100% reproduction rate on Telegram)
Regression: Likely introduced in recent channel routing refactor (needs bisection to confirm)
Fix complexity: Low (one-line change to use agent method consistently)
[Bug]: Sub-agent completion announce fails with "unsupported channel: telegram"
Summary
Sub-agent completion announcements fail silently when spawned from Telegram sessions. The Gateway attempts direct delivery 3 times, each failing with
unsupported channel: telegram, then gives up. The requester never receives notification that the sub-agent completed.This affects all sub-agents spawned from Telegram (both DMs and groups) using
sessions_spawn.Environment
sessions_spawntoolSteps to Reproduce
journalctl --user -u openclaw-gateway -fExpected Behavior
Actual Behavior
Subagent completion direct announce failed for run <id>: unsupported channel: telegramEvidence
Gateway Logs
Subagent Run Metadata
From
/home/openclaw/.openclaw/subagents/runs.json:{ "runId": "1495559a-7e44-465a-b24f-bd5d595fc4b4", "requesterSessionKey": "agent:main:main", "requesterOrigin": { "channel": "telegram", "to": "telegram:8517717047", "accountId": "default" }, "expectsCompletionMessage": true, "outcome": { "status": "ok" }, "announceRetryCount": 3, ← Tried 3 times "lastAnnounceRetryAt": 1771598814941, "cleanupCompletedAt": 1771598814941 }Root Cause Analysis
Looking at
src/agents/subagent-announce.ts, thesendSubagentAnnounceDirectly()function uses two delivery paths:expectsCompletionMessage=true): UsescallGateway({ method: "send", ... })callGateway({ method: "agent", ... })The
sendmethod path (used for completion messages) callssrc/gateway/server-methods/send.ts, which:normalizeChannelId(channelInput)getChannelPlugin(channel)to fetch the pluginnull, returnsunsupported channel: <channel>The bug: When
getChannelPlugin()is called during sub-agent announce, Telegram plugin may not be fully initialized at the Gateway level, causing it to returnnulleven though Telegram is configured and working.The
agentmethod path works fine because it routes through the standard agent execution pipeline, which properly resolves channels regardless of plugin initialization state.Impact
subagents list)Affected Channels
Based on code inspection, this likely affects:
Channels that likely work fine:
agentmethod fallback)Proposed Solution
Option 1: Always use
agentmethod for direct delivery (simplest, most consistent)Change
sendSubagentAnnounceDirectly()to always usecallGateway({ method: "agent", ... })instead of conditionally usingsend. Theagentmethod handles all deliverable channels correctly.Option 2: Fix channel plugin initialization race
Ensure
getChannelPlugin()always returns the correct plugin during sub-agent announce, even if called before full Gateway initialization.Option 3: Retry with
agentmethod onsendfailureIf
sendfails with "unsupported channel", fallback toagentmethod automatically.Recommendation: Option 1 — simplest, most consistent, eliminates the race condition entirely.
Related Issues
Additional Context
This bug was discovered when investigating why sub-agents consistently complete successfully but users never receive notifications. The sub-agent runs are logged in
subagents/runs.jsonwithstatus: "ok"andannounceRetryCount: 3, confirming the completion succeeded but delivery failed.The issue is specific to the direct announce delivery path and does not affect queued announces (which use a different code path through
enqueueAnnounce).Reproducible: Yes (100% reproduction rate on Telegram)
Regression: Likely introduced in recent channel routing refactor (needs bisection to confirm)
Fix complexity: Low (one-line change to use
agentmethod consistently)