Bug type
Behavior bug (incorrect output/state without crash)
Beta release blocker
No
Summary
On 2026.5.16-beta.7, dynamic tts tool calls in Discord and Telegram report success, synthesize valid Opus audio, and stage the generated audio under OpenClaw outbound media, but no channel provider send is invoked.
Steps to reproduce
- Run OpenClaw
2026.5.16-beta.7 with TTS and Discord or Telegram configured.
- In Discord or Telegram, ask the agent to send a TTS message.
- Let the agent invoke the dynamic
tts tool.
- Observe that the
tts tool reports success.
- Inspect generated media,
media/outbound, gateway logs, and channel history.
Expected behavior
A successful dynamic tts tool result should be delivered to the originating channel as audio/media.
If the tool reports success and OpenClaw stages a trusted local audio file under media/outbound, the relevant channel delivery path should receive a send request for that staged media.
This should hold even when normal final replies are private in message_tool_only channel contexts, because the tts tool contract says audio is auto-delivered from the tool result.
Actual behavior
The observed failure boundary is the same in both fresh traces:
tts tool succeeds -> valid local Opus is created -> media/outbound copy is staged -> no channel provider send is invoked
This is not an Opus encoding failure, not a TTS provider failure, and not a Discord/Telegram API rejection in the observed runs. The provider send path is not reached.
Discord evidence
Fresh observed Discord run:
Discord user message timestamp: 2026-05-18T13:40:09.091Z
Run ID: 999bd8e8-9393-4308-bf12-16b6619cc1f6
Session ID: b1fe8945-936e-4257-81d4-a4885c718857
TTS tool call timestamp: 2026-05-18T13:40:20.139Z
TTS tool result timestamp: 2026-05-18T13:40:22.330Z
The agent called tts with:
He never went out without a book under his arm, and he often came back with two.
The tool result was successful and returned:
(spoken) He never went out without a book under his arm, and he often came back with two.
Generated audio:
/tmp/openclaw/tts-Td3qRX/voice-1779111622307.opus
31841 bytes
OggS / OpusHead header
Staged outbound media:
/home/node/.openclaw/media/outbound/voice-1779111622307---7da79eac-7bc5-40d7-9159-9e452cd7ecba.ogg
31841 bytes
OggS / OpusHead header
mtime: 2026-05-18 23:40:24.859 +1000
Discord channel history after the request contained no bot reply and no attachment for this TTS run. Gateway log around the run showed the agent run starting but no message.action channel=discord and no Discord media send for the staged audio.
Telegram evidence
Fresh observed Telegram run:
Telegram inbound timestamp: 2026-05-18T13:53:53.895Z
Run ID: ba4a27c8-0d1a-43ba-81ef-ced81c9d6239
Session ID: f707824d-37ca-421a-bb9b-a6cd66343d91
TTS tool call timestamp: 2026-05-18T13:54:08.803Z
TTS tool result timestamp: 2026-05-18T13:54:12.170Z
The user requested an iconic line from Fiddler on the Roof. The agent called tts with:
For the OpenClaw TTS test: Tradition! (laughs) Short, iconic, and safely through the voice path.
The tool result was successful and returned:
(spoken) For the OpenClaw TTS test: Tradition! (laughs) Short, iconic, and safely through the voice path.
Generated audio:
/tmp/openclaw/tts-7TFPlU/voice-1779112452148.opus
54615 bytes
OggS / OpusHead header
Staged outbound media:
/home/node/.openclaw/media/outbound/voice-1779112452148---06ebe4c7-ee9d-4b41-8cd9-2efa6acdf79b.ogg
54615 bytes
OggS / OpusHead header
mtime: 2026-05-18 23:54:15.076 +1000
Gateway log shows Telegram inbound and agent run start, but no Telegram send after the TTS run. Earlier successful Telegram text replies in the same log emit lines such as:
telegram outbound send ok accountId=default chatId=6479169830 messageId=1237 operation=sendMessage deliveryKind=text chunkCount=1
No equivalent telegram outbound send ok, telegram sendMessage ok, sendVoice, sendAudio, or sendDocument appears for the fresh TTS run.
OpenClaw version
OpenClaw 2026.5.16-beta.7 tag: v2026.5.16-beta.7 commit: fff4532
Operating system
Linux container / OpenShift deployment.
Install method
docker
Model
codex/gpt-5.5
Provider / routing chain
TTS provider configuration is working in these runs. Synthesis produced valid local Opus files and OpenClaw staged them under media/outbound. The observed failure is after synthesis and outbound media staging.
Additional provider/model setup details
TTS provider configuration is working in these runs. Synthesis produced valid local Opus files and OpenClaw staged them under media/outbound.
The observed failure is after synthesis and outbound media staging.
Logs, screenshots, and evidence
Source pointers from `v2026.5.16-beta.7`:
- `src/agents/tools/tts-tool.ts` returns successful TTS output with `details.media.mediaUrl`, `trustedLocalMedia: true`, and optional `audioAsVoice`.
- `src/agents/tools/tts-tool.ts` describes the tool as: `Audio auto-delivered from tool result`.
- `src/auto-reply/reply/groups.ts` tells Discord/Telegram channel agents that normal final replies are private in `message_tool_only` contexts and visible output must use the message tool.
- `src/auto-reply/reply/dispatch-from-config.ts` suppresses source delivery when `sourceReplyDeliveryMode === "message_tool_only"` unless reply metadata has `deliverDespiteSourceReplySuppression`.
- `src/agents/pi-embedded-subscribe.handlers.tools.ts` can extract structured tool media and queue it.
- `src/agents/pi-embedded-runner/run/tool-media-payloads.ts` merges attempt tool media into reply payloads.
- `src/agents/pi-embedded-runner/run/tool-media-payloads.ts` explicitly avoids attaching tool media to `sourceReplyTranscriptMirror` payloads in `message_tool_only` mode.
- Discord and Telegram both have channel delivery paths capable of sending media-bearing payloads.
Runtime evidence from both fresh runs:
- The `tts` tool result succeeded.
- The generated temp audio file was valid Ogg/Opus.
- The staged outbound media file was valid Ogg/Opus.
- The final visible assistant mirror contained only text such as "Sent the TTS test..." and no media.
- Gateway logs show no channel send invocation for the staged audio.
Impact and severity
Affected: Discord and Telegram channel/direct TTS workflows observed on 2026.5.16-beta.7.
Severity: High for channel TTS workflows.
Frequency: 2/2 fresh observed attempts across two providers with the same failure boundary.
Consequence: The agent reports that TTS was sent, but the user receives no audio. This makes successful dynamic TTS misleading and effectively unusable on the observed channel paths.
Additional information
This should be treated as a shared dynamic-TTS channel-delivery bridge issue rather than separate Discord and Telegram adapter bugs.
Best current theory:
Dynamic tts media is generated and normalized, but it is not represented as a deliverable internal source reply in message_tool_only channel contexts. It therefore follows the ordinary final/tool output path and is suppressed by source-reply policy before it can invoke Discord or Telegram delivery.
The relevant contract mismatch appears to be:
- The
tts dynamic tool advertises: Audio auto-delivered from tool result.
- Discord/Telegram channel contexts use
sourceReplyDeliveryMode: "message_tool_only".
- In that mode, ordinary final/source delivery is suppressed unless reply metadata explicitly allows delivery despite source-reply suppression.
- Message-tool source replies get that internal delivery metadata.
- Dynamic
tts media does not appear to get equivalent treatment.
- Result: source-reply suppression wins, so the staged media never reaches Discord/Telegram delivery.
Suggested triage path:
- Trace the reply payload produced after a successful dynamic
tts tool result.
- Confirm whether that payload receives
deliverDespiteSourceReplySuppression or equivalent internal-source-reply metadata.
- Confirm whether the payload is skipped by
sourceReplyDeliveryMode: "message_tool_only" suppression before provider delivery.
- Decide whether dynamic TTS should emit/mark an internal source media reply, similar to message-tool source replies, so the auto-delivery contract is honored without making ordinary final text public.
- Add a regression test that asserts a successful dynamic
tts call in a message_tool_only Discord/Telegram-style context invokes channel delivery with the staged trusted local audio while keeping ordinary final text private.
Bug type
Behavior bug (incorrect output/state without crash)
Beta release blocker
No
Summary
On
2026.5.16-beta.7, dynamicttstool calls in Discord and Telegram report success, synthesize valid Opus audio, and stage the generated audio under OpenClaw outbound media, but no channel provider send is invoked.Steps to reproduce
2026.5.16-beta.7with TTS and Discord or Telegram configured.ttstool.ttstool reports success.media/outbound, gateway logs, and channel history.Expected behavior
A successful dynamic
ttstool result should be delivered to the originating channel as audio/media.If the tool reports success and OpenClaw stages a trusted local audio file under
media/outbound, the relevant channel delivery path should receive a send request for that staged media.This should hold even when normal final replies are private in
message_tool_onlychannel contexts, because thettstool contract says audio is auto-delivered from the tool result.Actual behavior
The observed failure boundary is the same in both fresh traces:
This is not an Opus encoding failure, not a TTS provider failure, and not a Discord/Telegram API rejection in the observed runs. The provider send path is not reached.
Discord evidence
Fresh observed Discord run:
The agent called
ttswith:The tool result was successful and returned:
Generated audio:
Staged outbound media:
Discord channel history after the request contained no bot reply and no attachment for this TTS run. Gateway log around the run showed the agent run starting but no
message.action channel=discordand no Discord media send for the staged audio.Telegram evidence
Fresh observed Telegram run:
The user requested an iconic line from Fiddler on the Roof. The agent called
ttswith:The tool result was successful and returned:
Generated audio:
Staged outbound media:
Gateway log shows Telegram inbound and agent run start, but no Telegram send after the TTS run. Earlier successful Telegram text replies in the same log emit lines such as:
No equivalent
telegram outbound send ok,telegram sendMessage ok,sendVoice,sendAudio, orsendDocumentappears for the fresh TTS run.OpenClaw version
OpenClaw 2026.5.16-beta.7 tag: v2026.5.16-beta.7 commit: fff4532
Operating system
Linux container / OpenShift deployment.
Install method
docker
Model
codex/gpt-5.5
Provider / routing chain
TTS provider configuration is working in these runs. Synthesis produced valid local Opus files and OpenClaw staged them under
media/outbound. The observed failure is after synthesis and outbound media staging.Additional provider/model setup details
TTS provider configuration is working in these runs. Synthesis produced valid local Opus files and OpenClaw staged them under
media/outbound.The observed failure is after synthesis and outbound media staging.
Logs, screenshots, and evidence
Impact and severity
Affected: Discord and Telegram channel/direct TTS workflows observed on
2026.5.16-beta.7.Severity: High for channel TTS workflows.
Frequency: 2/2 fresh observed attempts across two providers with the same failure boundary.
Consequence: The agent reports that TTS was sent, but the user receives no audio. This makes successful dynamic TTS misleading and effectively unusable on the observed channel paths.
Additional information
This should be treated as a shared dynamic-TTS channel-delivery bridge issue rather than separate Discord and Telegram adapter bugs.
Best current theory:
Dynamic
ttsmedia is generated and normalized, but it is not represented as a deliverable internal source reply inmessage_tool_onlychannel contexts. It therefore follows the ordinary final/tool output path and is suppressed by source-reply policy before it can invoke Discord or Telegram delivery.The relevant contract mismatch appears to be:
ttsdynamic tool advertises:Audio auto-delivered from tool result.sourceReplyDeliveryMode: "message_tool_only".ttsmedia does not appear to get equivalent treatment.Suggested triage path:
ttstool result.deliverDespiteSourceReplySuppressionor equivalent internal-source-reply metadata.sourceReplyDeliveryMode: "message_tool_only"suppression before provider delivery.ttscall in amessage_tool_onlyDiscord/Telegram-style context invokes channel delivery with the staged trusted local audio while keeping ordinary final text private.