#3186: fix(telegram): sanitize update offset + lock polling
channel: telegram
Cluster:
Telegram Command Fixes
This prevents Telegram polling from silently getting stuck when persisted state is corrupted and avoids multi-poller conflicts.
Changes:
- Validate persisted `lastUpdateId` (must be a safe integer within the 32-bit Bot API range). If invalid, back up the file and start from a null offset.
- Add a per-bot polling lock (account + token hash) to prevent multiple concurrent `getUpdates` loops.
- Wire the lock + offset sanitize into the polling monitor.
Notes:
- Cross-platform: no systemd dependencies.
- Escape hatch: set `CLAWDBOT_ALLOW_MULTI_TELEGRAM_POLL=1` to disable the poll lock.
Tests:
- `pnpm vitest run src/telegram/update-offset-store.test.ts src/telegram/poll-lock.test.ts`
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR hardens Telegram long-polling by (1) validating and backing up corrupted persisted `lastUpdateId` state before starting, and (2) adding a per-bot polling lock (account + token hash) to prevent multiple concurrent `getUpdates` loops. The monitor now acquires the lock before starting polling, logs invalid offset recovery via `onInvalid`, and ensures the lock is released on exit (including webhook mode).
<h3>Confidence Score: 4/5</h3>
- This PR is generally safe to merge, with low-to-moderate risk around edge-case lock reclamation and test flakiness.
- Core behavior changes (offset sanitization + file backup, single-poller lock acquisition/release) are straightforward and covered by targeted unit tests. Main remaining concerns are an edge case where lock owner detection can misclassify a reused PID as alive on Linux when startTime isn’t available, and the new timing-sensitive test which may be flaky under CI load.
- src/telegram/poll-lock.ts, src/telegram/poll-lock.test.ts
<!-- greptile_other_comments_section -->
<sub>(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#11347: fix: scope Telegram update offset to bot token
by anooprdawar · 2026-02-07
86.1%
#8166: fix(telegram): lifecycle fixes for duplicate messages and auto-reco...
by cheenu1092-oss · 2026-02-03
84.7%
#6463: fix(telegram): improve timeout handling and prevent channel exits
by ai-fanatic · 2026-02-01
84.3%
#11273: fix(telegram): prevent status command crash during thinking
by avirweb · 2026-02-07
82.5%
#10850: fix(telegram): await runner.stop() to prevent polling race conditio...
by talhaorak · 2026-02-07
82.0%
#11132: fix(telegram): guard command menu overflow and doctor warnings
by kiminbean · 2026-02-07
81.4%
#23238: fix(telegram): account named "default" silently breaks inbound polling
by anillBhoi · 2026-02-22
81.4%
#6447: fix(telegram): auto-restart polling when grammY runner exits silently
by AugmentAdvertise · 2026-02-01
80.9%
#7247: fix(telegram): abort stale getUpdates connections after long-poll t...
by JanderV · 2026-02-02
80.8%
#22363: fix(telegram): isolate update offset state by bot token
by AIflow-Labs · 2026-02-21
80.6%