← Back to PRs

#17629: fix(telegram): fall back to plain text when HTML formatter produces empty output

by Glucksberg open 2026-02-16 01:18 View on GitHub →
channel: telegram size: S experienced-contributor
Fixes #6652 ## Problem When a reply contains markdown tables or certain markdown constructs (e.g. bare `[]()` links), the Telegram HTML formatter can produce empty output. This results in a `400: Bad Request: message text is empty` error from the Telegram API, and the message is silently lost. ## Fix Approach Three layers of defense against empty HTML output: 1. **Auto-detect markdown tables** — `format.ts` now detects markdown table syntax (pipe-delimited rows with a divider line) and automatically applies `tableMode: "code"` to render them inside `<pre><code>` blocks instead of dropping them. 2. **`ensureNonEmptyTelegramHtml()` safety net** — Both `markdownToTelegramHtml()` and `markdownToTelegramChunks()` now check if the rendered HTML is empty. If so, they fall back to HTML-escaped plain text, ensuring output is never silently empty. 3. **Delivery-level fallback** — Both `delivery.ts` (bot mode) and `send.ts` (direct API mode) now check for empty HTML *before* calling the Telegram API. If detected, they send the message as unformatted plain text instead, logging a warning. ## Changed Files - **`src/telegram/format.ts`** — Added table auto-detection (`hasMarkdownTableSyntax`, `resolveTelegramTableMode`), `ensureNonEmptyTelegramHtml()` fallback, applied to both `markdownToTelegramHtml` and `markdownToTelegramChunks` - **`src/telegram/bot/delivery.ts`** — Pre-send empty HTML check with plain text fallback; refactored parse-error fallback to share params - **`src/telegram/send.ts`** — Same pre-send empty HTML check for the direct send path - **`src/telegram/format.test.ts`** — Tests for table auto-detection, empty-render fallback, and chunk fallback - **`src/telegram/bot/delivery.test.ts`** — Test for delivery-level empty HTML fallback ## Test Results All 3 new test cases pass. 158 lines changed across 5 files. <!-- greptile_comment --> <h3>Greptile Summary</h3> Adds three-layer defense against empty HTML output from markdown formatter in Telegram integration: - Auto-detects markdown tables and renders them in code blocks to prevent empty output - `ensureNonEmptyTelegramHtml()` fallback in `format.ts` returns HTML-escaped plain text when rendering produces empty output - Pre-send empty HTML checks in both `delivery.ts` and `send.ts` to send as plain text instead of failing with Telegram API error The fix comprehensively addresses the issue of messages being silently lost when markdown constructs like bare `[]()` links or tables produce empty HTML, ensuring users always receive their messages. <h3>Confidence Score: 5/5</h3> - This PR is safe to merge with minimal risk - it adds defensive fallback logic without breaking existing functionality - The changes are well-structured defensive programming that prevents message loss. The implementation includes comprehensive test coverage for the new fallback logic, maintains backward compatibility by only activating fallbacks when HTML is empty, and follows existing patterns in the codebase. The three-layer approach (table auto-detection, format-level fallback, delivery-level fallback) ensures robustness. - No files require special attention <sub>Last reviewed commit: 0700167</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs