Skip to content

[Bug]: webhookUrl configured but long-polling transport still runs getUpdates, continuously wiping the registered webhook #90254

Description

@travellingsoldier85

Summary

When channels.telegram.webhookUrl is configured, OpenClaw continues running its long-polling transport in the background. This polling transport periodically calls getUpdates, which causes Telegram to silently delete the registered webhook. The result is a continuous wipe cycle: webhook is set on startup → polling transport issues getUpdates ~30s later → Telegram interprets this as "switch to polling mode" and clears the webhook → inbound messages are lost until the webhook is manually re-registered.

Version

OpenClaw 2026.6.1 (confirmed via openclaw --version)

Steps to reproduce

  1. Configure channels.telegram.webhookUrl + channels.telegram.webhookSecret in openclaw.json
  2. Start or restart the gateway
  3. Observe via getWebhookInfo: webhook URL is set immediately after startup
  4. Wait 20–35 seconds
  5. Observe via getWebhookInfo: webhook URL is now empty — cleared by Telegram
  6. Repeat step 4–5: it wipes every ~30 seconds continuously as long as the gateway runs

Root cause

The long-polling watchdog (pollingStallThresholdMs) runs even when webhookUrl is configured — OpenClaw has no pure-webhook mode. The polling transport calls getUpdates on its liveness cycle; per Telegram Bot API specification, calling getUpdates while a webhook is active automatically deletes the webhook (this is documented Telegram behaviour, not a Telegram bug).

From the OpenClaw docs (channels/telegram.md):

"Long polling is the default mode; webhook mode is optional."
"A still-active webhook surfaces as a getUpdates conflict; OpenClaw then rebuilds the Telegram transport and retries webhook cleanup."

This confirms the polling path always runs. The pollingStallThresholdMs config key (range 30000600000) only tunes the watchdog timing — it does not disable polling.

The complete channels.telegram schema was enumerated via openclaw config schema lookup channels.telegram. There is no disablePolling, mode: "webhook", webhookOnly, transport, or any flag to stop the poller when in webhook mode.

Impact

  • Inbound Telegram DMs and group messages silently dropped for ~30s windows every minute
  • Every gateway restart resets the webhook → DM blackout until manually re-registered
  • Even with webhookUrl configured, the bot receives no messages unless an external process continuously re-asserts setWebhook

Current workaround

A systemd timer fires every 15s, calls setWebhook via getWebhookInfo check (never getUpdates), and re-asserts the webhook before the next polling wipe. This works but is a band-aid.

# /etc/systemd/system/tg-webhook-guard.timer
[Timer]
OnBootSec=20s
OnUnitActiveSec=15s
AccuracySec=1s

Requested fix

Add a disablePolling: true or transport: "webhook" config flag to channels.telegram that:

  1. Skips starting the long-polling transport entirely when webhookUrl is set
  2. Does NOT call getUpdates or deleteWebhook during normal operation
  3. Only uses the webhook listener path for inbound messages

Alternatively, make webhook mode the automatic behaviour when webhookUrl is configured (breaking change, but semantically correct).

Evidence

Gateway log shows liveness warning: eventLoopDelayP99Ms=4099 alongside continuous polling transport restarts. Empirical test: set webhook, poll getWebhookInfo every 10s with no guard running:

T+0s   → set
T+10s  → https://example.com/telegram-webhook  ✅
T+20s  → https://example.com/telegram-webhook  ✅
T+30s  → (empty)  ❌  ← wiped by getUpdates
T+40s  → (empty)

Reproduced across 3 independent gateway restarts on OpenClaw 2026.6.1.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions