Description
When running a single gateway with multiple Telegram bot accounts (8 in our case), the gateway produces persistent 409 Conflict errors on getUpdates — even though every account has a unique bot token.
Environment
- OpenClaw version:
2026.3.31 (213a704)
- Node.js:
22.22.1
- OS: Ubuntu Linux (x64)
- Config: 8 Telegram bot accounts (
ada, florence, graunt, ivo, jaque, joe, pretzel, ria), each with a unique botToken and 1:1 agent binding
Steps to reproduce
- Configure 2+ Telegram bot accounts in
channels.telegram.accounts, each with a distinct botToken
- Start the gateway
- Observe journal logs:
getUpdates conflict: terminated by other getUpdates request
Observed behavior
- With 1 bot account enabled: zero conflicts
- With 8 bot accounts enabled: ~2 conflicts/minute (after applying mitigations below)
- Errors always show
offset=0, suggesting the conflicting poll loop does not read the persisted offset
- Before mitigations, the conflict rate was 30+/minute and came in pairs
Mitigations applied (partial fixes)
default account had no enabled: false — it inherited another account's token and created a duplicate polling loop. Adding "enabled": false to the default account cut conflicts roughly in half.
network.autoSelectFamily: false in the channels.telegram config block — eliminated the IPv6→IPv4 fallback (fetch fallback: enabling sticky IPv4-only dispatcher) that caused dual requests during the transition window.
These two fixes reduced conflicts from ~30+/min to ~2/min. The remaining conflicts appear to be caused by HTTP connection pooling: all 8 bots poll 149.154.166.110:443 and their long-poll getUpdates requests seem to interfere with each other at the connection/dispatcher level (undici/grammY).
Expected behavior
Multiple bot accounts with distinct tokens should poll independently without 409 Conflict errors.
Possible root cause
The gateway appears to share an HTTP connection pool (undici dispatcher) across all Telegram bot accounts. Since all bots target the same Telegram API server (149.154.166.110), HTTP/2 multiplexing or HTTP/1.1 keep-alive connection reuse may cause getUpdates long-poll requests from different bots to collide on the same connection. Each bot account should ideally use its own isolated dispatcher/connection pool.
Additional observations
- TCP connections to Telegram (
ss -tnp): 9 connections for 8 bots (close to 1:1, but not strictly isolated)
- The
streaming: "partial" setting on accounts did not significantly affect conflict rate
- The
default account's update-offset-default.json persisted a botId matching another account (ada), suggesting the default account was silently sharing ada's token
Suggested fix
- Ensure the
default account does not inherit or share tokens from named accounts
- Create one undici
Agent/Pool per Telegram bot account to prevent connection-level interference between independent long-poll sessions
Description
When running a single gateway with multiple Telegram bot accounts (8 in our case), the gateway produces persistent
409 Conflicterrors ongetUpdates— even though every account has a unique bot token.Environment
2026.3.31 (213a704)22.22.1ada,florence,graunt,ivo,jaque,joe,pretzel,ria), each with a uniquebotTokenand 1:1 agent bindingSteps to reproduce
channels.telegram.accounts, each with a distinctbotTokengetUpdates conflict: terminated by other getUpdates requestObserved behavior
offset=0, suggesting the conflicting poll loop does not read the persisted offsetMitigations applied (partial fixes)
defaultaccount had noenabled: false— it inherited another account's token and created a duplicate polling loop. Adding"enabled": falseto thedefaultaccount cut conflicts roughly in half.network.autoSelectFamily: falsein thechannels.telegramconfig block — eliminated the IPv6→IPv4 fallback (fetch fallback: enabling sticky IPv4-only dispatcher) that caused dual requests during the transition window.These two fixes reduced conflicts from ~30+/min to ~2/min. The remaining conflicts appear to be caused by HTTP connection pooling: all 8 bots poll
149.154.166.110:443and their long-pollgetUpdatesrequests seem to interfere with each other at the connection/dispatcher level (undici/grammY).Expected behavior
Multiple bot accounts with distinct tokens should poll independently without
409 Conflicterrors.Possible root cause
The gateway appears to share an HTTP connection pool (undici dispatcher) across all Telegram bot accounts. Since all bots target the same Telegram API server (
149.154.166.110), HTTP/2 multiplexing or HTTP/1.1 keep-alive connection reuse may causegetUpdateslong-poll requests from different bots to collide on the same connection. Each bot account should ideally use its own isolated dispatcher/connection pool.Additional observations
ss -tnp): 9 connections for 8 bots (close to 1:1, but not strictly isolated)streaming: "partial"setting on accounts did not significantly affect conflict ratedefaultaccount'supdate-offset-default.jsonpersisted abotIdmatching another account (ada), suggesting the default account was silently sharing ada's tokenSuggested fix
defaultaccount does not inherit or share tokens from named accountsAgent/Poolper Telegram bot account to prevent connection-level interference between independent long-poll sessions