#7218: fix(telegram): skip empty text messages in threaded mode
channel: telegram
Cluster:
Telegram Message Handling Fixes
In Telegram threaded mode, natural chat replies were being sent with empty message bodies, causing 400 errors from the Telegram API ("message text is empty").
Root cause: When a reply payload has only whitespace or tag-stripped content, the text becomes empty but still reaches the Telegram API because:
1. The chunk loop didn't check for empty HTML content
2. sendTelegramText() had no validation unlike sendMessageTelegram()
This fix adds:
- Empty chunk validation in the delivery loop (skip chunks with empty HTML)
- Early return in sendTelegramText() for empty/whitespace text
Co-authored by Claude Code
Fixes #7186
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR tightens Telegram reply delivery in threaded mode by skipping empty chunks in the text-only send loop and adding an early return in `sendTelegramText()` when the input is empty/whitespace, preventing Telegram API 400s for “message text is empty”. The change lives entirely in `src/telegram/bot/delivery.ts`, affecting how markdown is chunked/converted to HTML and ultimately passed into `bot.api.sendMessage`.
Main thing to double-check is that the emptiness checks match what’s actually sent: `sendTelegramText()` may transform `text` into `htmlText` (or fall back to `plainText`), so validating only the pre-transform `text.trim()`/`chunk.html.trim()` can still allow an empty final payload (or skip a payload that would send via fallback).
<h3>Confidence Score: 4/5</h3>
- This PR is likely safe to merge and fixes the reported Telegram 400s, with a small chance of remaining edge cases around HTML/markdown transformations.
- Change scope is small and targeted (skipping empty chunks and early-returning on empty text). The main remaining risk is mismatch between what’s checked for emptiness (`text`/`chunk.html`) vs what’s actually sent (`htmlText` or fallback `plainText`), which could leave rare cases where Telegram still receives an empty message.
- src/telegram/bot/delivery.ts (validate emptiness on the final outgoing message string in both normal and fallback send paths)
<!-- greptile_other_comments_section -->
<sub>(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!</sub>
**Context used:**
- Context from `dashboard` - CLAUDE.md ([source](https://app.greptile.com/review/custom-context?memory=fd949e91-5c3a-4ab5-90a1-cbe184fd6ce8))
- Context from `dashboard` - AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=0d0c8278-ef8e-4d6c-ab21-f5527e322f13))
<!-- /greptile_comment -->
Most Similar PRs
#17769: fix(telegram): preserve reply text in threaded mode dispatch
by Glucksberg · 2026-02-16
88.9%
#11340: Telegram: skip empty message text instead of throwing (#11238)
by lailoo · 2026-02-07
87.2%
#17629: fix(telegram): fall back to plain text when HTML formatter produces...
by Glucksberg · 2026-02-16
84.2%
#12936: fix(telegram): omit message_thread_id for private DM chats
by omair445 · 2026-02-09
80.5%
#17953: fix(telegram): prevent silent message loss and duplicate messages i...
by zuyan9 · 2026-02-16
80.0%
#7261: fix(telegram): preserve DM topic thread id for outbound media
by ViffyGwaanl · 2026-02-02
79.1%
#6457: fix(telegram): register commands for group scope + preserve topic t...
by dae-sun · 2026-02-01
78.9%
#2917: Slack: fix thread context + prevent reply spillover
by SocialNerd42069 · 2026-01-27
78.6%
#21898: fix(telegram): auto-detect captionable messages for editMessageCaption
by ptrkstr · 2026-02-20
78.5%
#14443: fix(telegram): skip General topic thread ID for all chat types (#14...
by lailoo · 2026-02-12
78.0%