Skip to content

fix(telegram): clear stale retain before transient final fallback#41763

Merged
obviyus merged 2 commits intomainfrom
codex/telegram-clear-stale-retain-flag
Mar 11, 2026
Merged

fix(telegram): clear stale retain before transient final fallback#41763
obviyus merged 2 commits intomainfrom
codex/telegram-clear-stale-retain-flag

Conversation

@obviyus
Copy link
Contributor

@obviyus obviyus commented Mar 10, 2026

Summary

  • Problem: retainPreviewOnCleanupByLane could stay true after an archived-preview retain and leak into a later transient final on the same lane.
  • Why it matters: when that later final fell back to sendPayload, cleanup skipped stream.clear() and left a stale partial preview next to the fallback-sent final message.
  • What changed: clear the retain flag only when a lane is still in the transient preview lifecycle, then let the current final attempt set it back if it really retains the preview.
  • What did NOT change (scope boundary): no new fallback behavior, no new preview-state model, no changes outside Telegram final-preview cleanup.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

User-visible / Behavior Changes

  • Telegram multi-message draft streams no longer leave a stale partial preview visible when an earlier archived preview was retained but a later transient final falls back to a normal send.

Security Impact (required)

  • New permissions/capabilities? (No)
  • Secrets/tokens handling changed? (No)
  • New/changed network calls? (No)
  • Command/tool execution surface changed? (No)
  • Data access scope changed? (No)
  • If any Yes, explain risk + mitigation:

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: local repo checkout
  • Model/provider: n/a
  • Integration/channel (if any): Telegram
  • Relevant config (redacted): streamMode partial

Steps

  1. Stream message A so its preview is archived.
  2. Retain that archived preview path via message to edit not found, then send message B as the active preview.
  3. Make B's final edit fail pre-connect so it falls back to sendPayload.

Expected

  • Cleanup clears B's stale active preview before exit.

Actual

  • Before this fix, the stale retain flag skipped cleanup and left the partial preview visible beside the fallback-sent final.

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios: targeted Vitest coverage for src/telegram/lane-delivery.test.ts, src/telegram/bot-message-dispatch.test.ts, and src/telegram/network-errors.test.ts; pnpm tsgo.
  • Edge cases checked: existing regression that finalized previews stay visible when extra final payloads are sent still passes; new regression covers archived retain followed by transient fallback-send cleanup.
  • What you did not verify: live Telegram delivery.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? (Yes)
  • Config/env changes? (No)
  • Migration needed? (No)
  • If yes, exact upgrade steps:

Failure Recovery (if this breaks)

  • How to disable/revert this change quickly: revert commit 87bf43145.
  • Files/config to restore: src/telegram/lane-delivery-text-deliverer.ts, src/telegram/bot-message-dispatch.test.ts
  • Known bad symptoms reviewers should watch for: stale Telegram preview bubbles surviving after a fallback-sent final, or finalized previews being cleared by later extra final payloads.

Risks and Mitigations

  • Risk: the retain reset could clear protection for already-finalized previews.
    • Mitigation: reset is gated to activePreviewLifecycleByLane === "transient", and the existing finalized-preview regression still passes.

@openclaw-barnacle openclaw-barnacle bot added channel: telegram Channel integration: telegram size: S maintainer Maintainer-authored PR labels Mar 10, 2026
@obviyus obviyus self-assigned this Mar 10, 2026
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 10, 2026

Greptile Summary

This PR fixes a subtle state-leak bug in Telegram's draft-stream delivery layer: retainPreviewOnCleanupByLane could remain true after an archived-preview "retained" result and silently suppress the stream.clear() call for a later transient final that fell back to a plain sendPayload, leaving a stale partial preview bubble visible beside the fallback-sent final message.

Changes:

  • src/telegram/lane-delivery-text-deliverer.ts: At the start of every final delivery for a lane whose lifecycle is still "transient", the retain flag is proactively reset to false. Any successful retain within the same final attempt sets it back, so no protection is lost; the guard is correctly skipped for "complete" lanes so extra final payloads never clear already-finalized messages.
  • src/telegram/bot-message-dispatch.test.ts: Adds a focused regression test that exercises the exact failure path — archived preview retained via "message to edit not found", followed by a transient final that falls back via ECONNREFUSED — and asserts both the fallback send and the stream.clear() cleanup call.

Confidence Score: 5/5

  • This PR is safe to merge — it is a minimal, well-scoped one-line guard that is gated behind an existing lifecycle predicate and cannot affect any code path outside Telegram transient-preview cleanup.
  • The production change is a single if guard (6 lines with comments) inside an already-isolated branch. The logic is sound: resetting the flag before each transient final attempt is idempotent when no archived retain occurs, and when a retain does occur the downstream code immediately re-sets the flag, so existing behaviour is fully preserved. The lifecycle guard ("transient") ensures completed previews are never disturbed. The new regression test precisely models the broken scenario, the assertions cover all relevant side-effects (intermediate edits, fallback send, and the crucial clear() call), and the PR author confirms existing finalized-preview regressions still pass.
  • No files require special attention.

Last reviewed commit: 50646aa

@obviyus obviyus force-pushed the codex/telegram-clear-stale-retain-flag branch from 50646aa to c094083 Compare March 11, 2026 16:05
@obviyus obviyus merged commit daf8afc into main Mar 11, 2026
10 checks passed
@obviyus obviyus deleted the codex/telegram-clear-stale-retain-flag branch March 11, 2026 16:06
@obviyus
Copy link
Contributor Author

obviyus commented Mar 11, 2026

Merged via squash.

Thanks @obviyus!

davidemanuelDEV pushed a commit to davidemanuelDEV/openclaw that referenced this pull request Mar 11, 2026
…enclaw#41763)

Merged via squash.

Prepared head SHA: c094083
Co-authored-by: obviyus <[email protected]>
Co-authored-by: obviyus <[email protected]>
Reviewed-by: @obviyus
mrosmarin added a commit to mrosmarin/openclaw that referenced this pull request Mar 11, 2026
* main:
  fix(agents): check billing errors before context overflow heuristics (openclaw#40409)
  fix(config): add missing editMessage and createForumTopic to Telegram actions schema (openclaw#35498)
  fix(signal): add missing accountUuid to Zod config schema (openclaw#35578)
  fix(voice-call): add speed and instructions to OpenAI TTS config schema (openclaw#39226)
  fix(telegram): clear stale retain before transient final fallback (openclaw#41763)
  Fix env proxy bootstrap for model traffic (openclaw#43248)
  fix: tighten Ollama onboarding cloud handling (openclaw#41529) (thanks @BruceMacD)
  Onboard: add Ollama auth flow and improve model defaults
dhoman pushed a commit to dhoman/chrono-claw that referenced this pull request Mar 11, 2026
…enclaw#41763)

Merged via squash.

Prepared head SHA: c094083
Co-authored-by: obviyus <[email protected]>
Co-authored-by: obviyus <[email protected]>
Reviewed-by: @obviyus
hydro13 pushed a commit to hydro13/openclaw that referenced this pull request Mar 12, 2026
…enclaw#41763)

Merged via squash.

Prepared head SHA: c094083
Co-authored-by: obviyus <[email protected]>
Co-authored-by: obviyus <[email protected]>
Reviewed-by: @obviyus
Ruijie-Ysp pushed a commit to Ruijie-Ysp/clawdbot that referenced this pull request Mar 12, 2026
…enclaw#41763)

Merged via squash.

Prepared head SHA: c094083
Co-authored-by: obviyus <[email protected]>
Co-authored-by: obviyus <[email protected]>
Reviewed-by: @obviyus
plabzzxx pushed a commit to plabzzxx/openclaw that referenced this pull request Mar 13, 2026
…enclaw#41763)

Merged via squash.

Prepared head SHA: c094083
Co-authored-by: obviyus <[email protected]>
Co-authored-by: obviyus <[email protected]>
Reviewed-by: @obviyus
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: telegram Channel integration: telegram maintainer Maintainer-authored PR size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant