From f154926cc0dc52898b23d183a1b500a0f5bf1f5c Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Tue, 24 Feb 2026 22:33:08 +0530 Subject: [PATCH] fix: land telegram empty-html fallback hardening (#25096) (thanks @Glucksberg) --- CHANGELOG.md | 1 + src/telegram/bot/delivery.test.ts | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 25dfd536167..e44e3d32b9c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ Docs: https://docs.openclaw.ai - Security/Native images: enforce `tools.fs.workspaceOnly` for native prompt image auto-load (including history refs), preventing out-of-workspace sandbox mounts from being implicitly ingested as vision input. This ships in the next npm release. Thanks @tdjackey for reporting. - Security/Exec approvals: bind `system.run` command display/approval text to full argv when shell-wrapper inline payloads carry positional argv values, and reject payload-only `rawCommand` mismatches for those wrapper-carrier forms, preventing hidden command execution under misleading approval text. This ships in the next npm release. Thanks @tdjackey for reporting. - Telegram/Media fetch: prioritize IPv4 before IPv6 in SSRF pinned DNS address ordering so media downloads still work on hosts with broken IPv6 routing. (#24295, #23975) Thanks @Glucksberg. +- Telegram/Replies: when markdown formatting renders to empty HTML (for example syntax-only chunks in threaded replies), retry delivery with plain text, and fail loud when both formatted and plain payloads are empty to avoid false delivered states. (#25096, #25091) Thanks @Glucksberg. - Sessions/Tool-result guard: avoid generating synthetic `toolResult` entries for assistant turns that ended with `stopReason: "aborted"` or `"error"`, preventing orphaned tool-use IDs from triggering downstream API validation errors. (#25429) Thanks @mikaeldiakhate-cell. - Usage accounting: parse Moonshot/Kimi `cached_tokens` fields (including `prompt_tokens_details.cached_tokens`) into normalized cache-read usage metrics. (#25436) Thanks @Elarwei001. - Doctor/Sandbox: when sandbox mode is enabled but Docker is unavailable, surface a clear actionable warning (including failure impact and remediation) instead of a mild “skip checks” note. (#25438) Thanks @mcaxtr. diff --git a/src/telegram/bot/delivery.test.ts b/src/telegram/bot/delivery.test.ts index 846f5b409db..971ee679c26 100644 --- a/src/telegram/bot/delivery.test.ts +++ b/src/telegram/bot/delivery.test.ts @@ -245,7 +245,7 @@ describe("deliverReplies", () => { }); it("falls back to plain text when markdown renders to empty HTML in threaded mode", async () => { - const runtime = { error: vi.fn(), log: vi.fn() }; + const runtime = createRuntime(); const sendMessage = vi.fn(async (_chatId: string, text: string) => { if (text === "") { throw new Error("400: Bad Request: message text is empty"); @@ -279,7 +279,7 @@ describe("deliverReplies", () => { }); it("throws when formatted and plain fallback text are both empty", async () => { - const runtime = { error: vi.fn(), log: vi.fn() }; + const runtime = createRuntime(); const sendMessage = vi.fn(); const bot = { api: { sendMessage } } as unknown as Bot;