Bug Description
@chat-adapter/telegram silently discards the remainder of long messages. postMessage() renders the postable content, passes the rendered text through truncateForTelegram(..., 4096, ...), and sends only the truncated result.
This is especially surprising for { markdown } messages: MarkdownV2 escaping expands the wire payload, so source text can be cut substantially before its own length reaches the apparent platform boundary. The caller receives a successful SentMessage and has no indication that content was lost.
This is the concrete Telegram symptom of the broader contract problem discussed in #408.
Steps to Reproduce
- Create a Chat SDK bot using
@chat-adapter/telegram.
- In a Telegram handler, post a Markdown response whose rendered MarkdownV2 output exceeds 4,096 characters.
- Trigger the handler from Telegram.
- Observe that Telegram receives one message ending in an ellipsis and never receives the remainder.
Expected Behavior
Long Telegram posts should not silently lose content. When configured to split long messages, the adapter should send the complete response as ordered consecutive messages, with each payload inside Telegram's limit and with valid formatting.
Short messages should continue to produce one Telegram message.
Actual Behavior
Only one Telegram message is sent. It is truncated to 4,096 characters after rendering, with an ellipsis appended. Everything after the cutoff is discarded.
Code Sample
import { createTelegramAdapter } from '@chat-adapter/telegram';
import { Chat } from 'chat';
const bot = new Chat({
userName: 'mybot',
adapters: {
telegram: createTelegramAdapter({ mode: 'polling' }),
},
});
bot.onNewMention(async (thread) => {
const longMarkdown = Array.from(
{ length: 200 },
(_, index) => `## Section ${index + 1}\n\n- Result with punctuation: value_${index}.`,
).join('\n\n');
await thread.post({ markdown: longMarkdown });
});
Chat SDK Version
chat@4.28.1, @chat-adapter/telegram@4.28.1
Node.js Version
24.14.0
Platform Adapter
Telegram
Operating System
macOS
Additional Context
In a real n8n Agent reproduction, the stored assistant response contained 6,291 source characters. Telegram cut the visible response around source character 3,932 because MarkdownV2 escaping expanded the rendered payload to the adapter's 4,096-character truncation boundary.
Current main still retains truncateForTelegram() for classic/fallback Telegram message paths. Newer rich-message support raises the ceiling for supported Bot API versions, but it does not eliminate silent data loss in fallback paths or above the rich-message limit.
A useful adapter-level resolution would be an explicit long-message strategy such as the "split" option proposed in #408. Splitting belongs in the adapter because it owns final rendering, Telegram-specific limits, formatting validity, and the semantics of returning one SentMessage for multiple API posts.

Bug Description
@chat-adapter/telegramsilently discards the remainder of long messages.postMessage()renders the postable content, passes the rendered text throughtruncateForTelegram(..., 4096, ...), and sends only the truncated result.This is especially surprising for
{ markdown }messages: MarkdownV2 escaping expands the wire payload, so source text can be cut substantially before its own length reaches the apparent platform boundary. The caller receives a successfulSentMessageand has no indication that content was lost.This is the concrete Telegram symptom of the broader contract problem discussed in #408.
Steps to Reproduce
@chat-adapter/telegram.Expected Behavior
Long Telegram posts should not silently lose content. When configured to split long messages, the adapter should send the complete response as ordered consecutive messages, with each payload inside Telegram's limit and with valid formatting.
Short messages should continue to produce one Telegram message.
Actual Behavior
Only one Telegram message is sent. It is truncated to 4,096 characters after rendering, with an ellipsis appended. Everything after the cutoff is discarded.
Code Sample
Chat SDK Version
chat@4.28.1,@chat-adapter/telegram@4.28.1Node.js Version
24.14.0
Platform Adapter
Telegram
Operating System
macOS
Additional Context
In a real n8n Agent reproduction, the stored assistant response contained 6,291 source characters. Telegram cut the visible response around source character 3,932 because MarkdownV2 escaping expanded the rendered payload to the adapter's 4,096-character truncation boundary.
Current
mainstill retainstruncateForTelegram()for classic/fallback Telegram message paths. Newer rich-message support raises the ceiling for supported Bot API versions, but it does not eliminate silent data loss in fallback paths or above the rich-message limit.A useful adapter-level resolution would be an explicit long-message strategy such as the
"split"option proposed in #408. Splitting belongs in the adapter because it owns final rendering, Telegram-specific limits, formatting validity, and the semantics of returning oneSentMessagefor multiple API posts.