Skip to content

fix(typing): add markDispatchIdle safety net to main reply pipeline#27250

Closed
Sid-Qin wants to merge 1 commit intoopenclaw:mainfrom
Sid-Qin:fix/27172-reply-pipeline-typing-idle
Closed

fix(typing): add markDispatchIdle safety net to main reply pipeline#27250
Sid-Qin wants to merge 1 commit intoopenclaw:mainfrom
Sid-Qin:fix/27172-reply-pipeline-typing-idle

Conversation

@Sid-Qin
Copy link
Contributor

@Sid-Qin Sid-Qin commented Feb 26, 2026

Summary

  • Problem: Telegram typing indicator ("typing...") persists indefinitely after agent runs complete. At least 7 separate issue reports in the last 2 hours describe the same symptom — the typing keepalive loop is never stopped because markDispatchIdle() never fires.
  • Why it matters: This is the fix: add @lid format support and allowFrom wildcard handling #1 reported bug today. Every Telegram user is affected. The only workaround is openclaw gateway restart, which is disruptive and temporary.
  • Root cause: The typing controller requires two signals to stop: markRunComplete() AND markDispatchIdle(). The followup runner was fixed in fix(typing): call markDispatchIdle in followup runner to prevent stuck indicator #26881 to call both in its finally block, but the main reply pipeline (agent-runner.ts) only calls markRunComplete(), relying on the dispatcher's onIdle callback for the second signal. If the dispatcher exits early, errors, or the reply path doesn't go through it cleanly, markDispatchIdle() is never called.
  • What changed: src/auto-reply/reply/agent-runner.ts — Added typing.markDispatchIdle() as a safety net in the finally block, identical to the fix(typing): call markDispatchIdle in followup runner to prevent stuck indicator #26881 followup runner fix.
  • What did NOT change: Typing controller logic, dispatcher behavior, followup runner, keepalive interval, TTL.

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 typing indicator now reliably stops when the agent run completes
  • No more "stuck typing" after normal inbound replies

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

Repro + Verification

Environment

  • OS: macOS 15.4
  • Runtime: Node 22
  • Integration/channel: Telegram

Steps

  1. Send a message to the bot on Telegram
  2. Wait for the reply to complete
  3. Observe the typing indicator

Expected

  • Typing indicator stops when reply is sent

Actual

  • Before fix: Typing indicator persists indefinitely (until 2-min TTL or gateway restart)
  • After fix: Typing indicator stops as soon as the run completes

Evidence

Tests: 76 passed (76) — src/auto-reply/reply/agent-runner*.test.ts (5 test files)

The fix is the same one-liner pattern proven in #26881 for the followup runner. Calling markDispatchIdle() twice is harmless — cleanup() is guarded by the active flag, and maybeStopOnIdle() only fires cleanup when both runComplete and dispatchIdle are true.

Human Verification (required)

  • Verified scenarios: main reply pipeline finally block now matches followup runner pattern
  • Edge cases checked: double-call is safe (guarded by active flag), dispatcher onIdle still works normally
  • What I did not verify: Live Telegram typing indicator behavior

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? No
  • Migration needed? No

Failure Recovery (if this breaks)

  • How to disable/revert: Revert this commit; typing indicator will rely solely on dispatcher's onIdle callback
  • Files/config to restore: src/auto-reply/reply/agent-runner.ts

Risks and Mitigations

None — this is a defensive safety net. The same pattern is already proven in production via #26881 for the followup runner. The typing controller's cleanup() is idempotent.

The typing controller requires both markRunComplete() and
markDispatchIdle() to stop the keepalive loop.  The followup runner
was fixed in openclaw#26881 to call both signals, but the main reply pipeline
in agent-runner.ts only calls markRunComplete() in its finally block,
relying on the dispatcher's onIdle callback for the second signal.

If the dispatcher exits early, errors, or the reply path doesn't go
through it cleanly, markDispatchIdle() is never called and the
Telegram typing indicator persists indefinitely.

Add the same safety-net pattern from openclaw#26881: call
typing.markDispatchIdle() in the finally block.  This is harmless
when the dispatcher fires normally — cleanup() is guarded by the
active flag — but prevents stuck indicators on every edge case.

Closes openclaw#27172
Closes openclaw#27174
Closes openclaw#27177
Closes openclaw#27219
Closes openclaw#27226
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 26, 2026

Greptile Summary

Adds defensive safety net to prevent stuck Telegram typing indicators by ensuring both cleanup signals (markRunComplete() and markDispatchIdle()) are called in the main reply pipeline's finally block.

  • Root cause: Typing controller requires two signals to stop. The dispatcher's onIdle callback normally fires markDispatchIdle(), but if the dispatcher exits early or errors, the second signal never fires and typing persists indefinitely.
  • Fix: Mirrors the proven pattern from fix(typing): call markDispatchIdle in followup runner to prevent stuck indicator #26881 (followup runner) by calling typing.markDispatchIdle() in the finally block as a safety net.
  • Safety: The cleanup() function is guarded by a sealed flag, making duplicate calls harmless. The typing controller's maybeStopOnIdle() only triggers cleanup when both flags are set.
  • Impact: Resolves the fix: add @lid format support and allowFrom wildcard handling #1 reported bug affecting all Telegram users (7+ issue reports in 2 hours).
  • Testing: All 76 agent-runner tests pass.

Confidence Score: 5/5

Last reviewed commit: 7b2239e

steipete added a commit that referenced this pull request Feb 26, 2026
@steipete
Copy link
Contributor

Landed on main via commit 199ef9f8e.

What was landed from this PR:

  • Added typing.markDispatchIdle() safety-net in runReplyAgent finalization so typing cleanup still runs when dispatcher onIdle does not fire.
  • Added changelog entry with attribution in 2026.2.26 (Unreleased).

Attribution:

  • Original PR commit: 7b2239ebe583c4e516ad8324b646e65dfc69d138
  • Landed commit: 199ef9f8e

Validation run before landing (/landpr flow):

  • pnpm lint: pass
  • pnpm build: pass
  • pnpm test: fail on pre-existing unrelated test (extensions/msteams/src/messenger.test.ts silent-prefix assertion), not in touched files.

Thanks @Sid-Qin for the fix.

@steipete steipete closed this Feb 26, 2026
robbyczgw-cla pushed a commit to robbyczgw-cla/openclaw that referenced this pull request Feb 26, 2026
…, thanks @Sid-Qin)

Co-authored-by: Sid Qin <s3734389@gmail.com>
execute008 pushed a commit to execute008/openclaw that referenced this pull request Feb 27, 2026
…, thanks @Sid-Qin)

Co-authored-by: Sid Qin <s3734389@gmail.com>
r4jiv007 pushed a commit to r4jiv007/openclaw that referenced this pull request Feb 28, 2026
…, thanks @Sid-Qin)

Co-authored-by: Sid Qin <s3734389@gmail.com>
vincentkoc pushed a commit to Sid-Qin/openclaw that referenced this pull request Feb 28, 2026
…, thanks @Sid-Qin)

Co-authored-by: Sid Qin <s3734389@gmail.com>
vincentkoc pushed a commit to rylena/rylen-openclaw that referenced this pull request Feb 28, 2026
…, thanks @Sid-Qin)

Co-authored-by: Sid Qin <s3734389@gmail.com>
steipete added a commit to Sid-Qin/openclaw that referenced this pull request Mar 2, 2026
…, thanks @Sid-Qin)

Co-authored-by: Sid Qin <s3734389@gmail.com>
robertchang-ga pushed a commit to robertchang-ga/openclaw that referenced this pull request Mar 2, 2026
…, thanks @Sid-Qin)

Co-authored-by: Sid Qin <s3734389@gmail.com>
dorgonman pushed a commit to kanohorizonia/openclaw that referenced this pull request Mar 3, 2026
…, thanks @Sid-Qin)

Co-authored-by: Sid Qin <s3734389@gmail.com>
zooqueen pushed a commit to hanzoai/bot that referenced this pull request Mar 6, 2026
…, thanks @Sid-Qin)

Co-authored-by: Sid Qin <s3734389@gmail.com>
vincentkoc pushed a commit to Sid-Qin/openclaw that referenced this pull request Feb 28, 2026
…, thanks @Sid-Qin)

Co-authored-by: Sid Qin <s3734389@gmail.com>
vincentkoc pushed a commit to rylena/rylen-openclaw that referenced this pull request Feb 28, 2026
…, thanks @Sid-Qin)

Co-authored-by: Sid Qin <s3734389@gmail.com>
steipete added a commit to Sid-Qin/openclaw that referenced this pull request Mar 2, 2026
…, thanks @Sid-Qin)

Co-authored-by: Sid Qin <s3734389@gmail.com>
robertchang-ga pushed a commit to robertchang-ga/openclaw that referenced this pull request Mar 2, 2026
…, thanks @Sid-Qin)

Co-authored-by: Sid Qin <s3734389@gmail.com>
dorgonman pushed a commit to kanohorizonia/openclaw that referenced this pull request Mar 3, 2026
…, thanks @Sid-Qin)

Co-authored-by: Sid Qin <s3734389@gmail.com>
zooqueen pushed a commit to hanzoai/bot that referenced this pull request Mar 6, 2026
…, thanks @Sid-Qin)

Co-authored-by: Sid Qin <s3734389@gmail.com>
thebenjaminlee pushed a commit to escape-velocity-ventures/openclaw that referenced this pull request Mar 7, 2026
…, thanks @Sid-Qin)

Co-authored-by: Sid Qin <s3734389@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment