#20842: fix(telegram): preserve preview when only error payloads are delivered
channel: telegram
size: S
Cluster:
Telegram Streaming Enhancements
## Summary
- Preserve the streaming preview message when only error payloads are delivered as final
- Prevents the agent's partial conversational response from being deleted when a tool fails
- User now sees both the agent's text AND the error, instead of just the error
## Problem
When a tool fails during a Telegram conversational response:
1. Agent types partial text (e.g., "Let me check that file...") → streaming preview message
2. Tool fails → error payload `⚠️ Tool failed` sent as new message (correct: `isError` blocks preview edit)
3. `finally` block: `finalizedViaPreviewMessage` is `false` → `draftStream.clear()` **deletes** the preview
4. User sees only the error; the agent's text is gone
## Root Cause
The `finally` block in `bot-message-dispatch.ts` unconditionally clears the draft stream when `finalizedViaPreviewMessage` is false. This is correct for stale/duplicated previews (e.g., long text sent via fallback), but incorrect when only error payloads were delivered — the preview contains unique partial agent text.
## Fix
Track whether a non-error final payload was delivered via `deliverReplies` fallback (`deliveredNonErrorFinalViaFallback`). In the `finally` block:
- **Clear** the preview when non-error text was sent as a new message (preview is stale)
- **Preserve** the preview when only error payloads were delivered (preview has unique content)
- **Clear** when nothing was delivered (abandoned preview)
## Changes
- `src/telegram/bot-message-dispatch.ts`: Add `deliveredNonErrorFinalViaFallback` flag, update `finally` block logic (+18 lines)
- `src/telegram/bot-message-dispatch.test.ts`: 3 new tests — error-only preserves preview, error-only with partial text, non-error fallback clears preview (+53 lines)
## Test plan
- [x] All 16 existing tests pass
- [x] New test: error-only final preserves preview message (not cleared)
- [x] New test: partial text + error-only final preserves preview
- [x] New test: non-error fallback (long text) still clears preview
- [ ] Manual: send message to Telegram bot, trigger tool failure, verify both text and error visible
Fixes #18244
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Preserves Telegram streaming preview messages when tool failures occur, preventing agent's partial conversational text from being deleted. The fix adds a `deliveredNonErrorFinalViaFallback` flag to distinguish between error-only scenarios (where preview should be preserved) and non-error fallback scenarios like long text (where preview is stale and should be cleared). The logic correctly handles all edge cases: preview edits, fallback deliveries, error-only finals, and abandoned previews.
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk
- The implementation correctly addresses the issue with clear logic, comprehensive test coverage (3 new tests covering all scenarios), and no breaking changes. The flag-based approach properly distinguishes between error-only finals (preserve preview) and non-error fallback deliveries (clear preview), while maintaining backward compatibility for preview edit and abandoned preview scenarios.
- No files require special attention
<sub>Last reviewed commit: 21f321d</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
---
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Testing: fully tested (automated + manual verification)
I understand and can explain all changes in this PR.
Most Similar PRs
#18678: fix(telegram): preserve draft message when all final payloads are e...
by julianubico · 2026-02-16
89.6%
#19375: telegram: align tool-error summaries
by NorthyIE · 2026-02-17
83.1%
#19399: telegram: fix MEDIA false positives and partial final drop
by HOYALIM · 2026-02-17
82.9%
#17953: fix(telegram): prevent silent message loss and duplicate messages i...
by zuyan9 · 2026-02-16
82.4%
#19235: fix(telegram): tool error warnings no longer overwrite streamed rep...
by gatewaybuddy · 2026-02-17
81.4%
#19479: fix(telegram): skip redundant final edit in partial streaming mode
by v8hid · 2026-02-17
81.2%
#19673: fix(telegram): avoid starting streaming replies with only 1-2 words
by emanuelst · 2026-02-18
80.3%
#19102: Fix Telegram per-message link preview override
by Clawborn · 2026-02-17
80.0%
#22763: feat: expose per-message linkPreview param in message tool
by chrysb · 2026-02-21
79.6%
#18460: fix(telegram): send fallback when streamMode partial drops all mess...
by BinHPdev · 2026-02-16
79.0%