Description
When an outbound Telegram message includes channelData (e.g., inline buttons, quote text), the delivery path goes through telegramOutbound.sendPayload() instead of sendText(). The sendPayload path sends the full text in a single sendMessage API call without chunking, causing Telegram to reject it with 400: Bad Request: message is too long.
The message then enters the delivery-recovery queue, retries, and is eventually permanently skipped (1 skipped (max retries)), silently dropping the user's message.
Root Cause
src/channels/plugins/outbound/telegram.ts — the telegramOutbound adapter correctly configures:
chunker: markdownToTelegramHtmlChunks,
textChunkLimit: 4000,
But these only take effect for the sendText path (via deliver.ts → sendTextChunks). The sendPayload path (L103-108) directly calls send(to, text, ...) without splitting.
Steps to Reproduce
- Have an OpenClaw agent generate a response longer than 4096 characters
- The response includes
channelData.telegram (e.g., inline buttons)
- Observe in gateway logs:
telegram message failed: Call to 'sendMessage' failed! (400: Bad Request: message is too long)
Delivery recovery complete: 0 recovered, 0 failed, 1 skipped (max retries)
Expected Behavior
Long messages should be automatically split into chunks ≤4000 chars using the existing markdownToTelegramHtmlChunks chunker, with inline buttons attached to the last chunk.
Environment
- OpenClaw 2026.2.26
- macOS (Darwin arm64)
- Node 25.6.1
Description
When an outbound Telegram message includes
channelData(e.g., inline buttons, quote text), the delivery path goes throughtelegramOutbound.sendPayload()instead ofsendText(). ThesendPayloadpath sends the full text in a singlesendMessageAPI call without chunking, causing Telegram to reject it with400: Bad Request: message is too long.The message then enters the delivery-recovery queue, retries, and is eventually permanently skipped (
1 skipped (max retries)), silently dropping the user's message.Root Cause
src/channels/plugins/outbound/telegram.ts— thetelegramOutboundadapter correctly configures:But these only take effect for the
sendTextpath (viadeliver.ts→sendTextChunks). ThesendPayloadpath (L103-108) directly callssend(to, text, ...)without splitting.Steps to Reproduce
channelData.telegram(e.g., inline buttons)Expected Behavior
Long messages should be automatically split into chunks ≤4000 chars using the existing
markdownToTelegramHtmlChunkschunker, with inline buttons attached to the last chunk.Environment