Skip to content
Back to skills

Polling Bot Offset Freeze Diagnosis

ASecurity

Diagnose and fix a frozen getUpdates offset in a cron-based Telegram (or similar long-poll) bot caused by two pollers consuming the same bot token. Use when a polling bot suddenly floods old messages, the update offset hasn't advanced for days, or more than one scheduled job calls getUpdates against one token.

  • 3 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 1, 2026
ai-agentsbashgitapisecurity

Works with

  • api

Security analysis

A93/100
  • highCreates or modifies cron jobs for persistent execution

Pro shows the line behind each finding and how to fix it

Scanned October 1, 2026

npx -y skills add williamblair333/Uncle-J-s-Refinery --skill polling-bot-offset-freeze-diagnosis --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Polling Bot Offset Freeze Diagnosis?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Polling Bot Offset Freeze Diagnosis
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/williamblair333-polling-bot-offset-freeze-diagnosis/badge)](https://www.skillsdirectory.com/skills/williamblair333-polling-bot-offset-freeze-diagnosis)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: polling-bot-offset-freeze-diagnosis
description: Diagnose and fix a frozen getUpdates offset in a cron-based Telegram (or similar long-poll) bot caused by two pollers consuming the same bot token. Use when a polling bot suddenly floods old messages, the update offset hasn't advanced for days, or more than one scheduled job calls getUpdates against one token.
---

# Polling-Bot Offset-Freeze Diagnosis

## When to use

A long-poll bot (Telegram `getUpdates`, or any single-consumer poll API) suddenly
re-delivers a backlog of old messages, or the stored offset hasn't moved in days.
Root cause is almost always **two consumers sharing one token**: each `getUpdates`
call ACKs only what *it* sees, so neither advances the shared offset past the
other's reads. The backlog never clears and re-floods on every trigger.

Distinct from backlog/age-filter issues (`polling-bot-backlog-diagnosis`,
`polling-bot-age-filter-fix`) — here the offset is *frozen*, not just old. Fixing
the age filter alone will not unstick a frozen offset.

## Diagnostic steps (verify live state before changing anything)

1. **Read prior incident notes first.** Check memweave and any gitignored
   local-only incident forensics before touching code — the freeze may already
   be characterized.

2. **Confirm the offset is actually frozen.** Read the persisted offset file and
   its mtime. A days-old mtime with a live cron means the value isn't advancing:
   ```bash
   stat -c '%y' state/<offset-file>     # last write time
   cat state/<offset-file>              # current offset value
   ```

3. **Confirm the re-skip loop in the log.** A fresh log timestamp showing the
   poller skipping the same stale backlog every interval (not advancing) confirms
   the bot re-reads and re-discards the same updates each run.

4. **Find the competing consumers.** Enumerate every job that calls the poll API
   against the token — crontab plus any service/daemon:
   ```bash
   crontab -l | grep -i <bot-or-poll-name>
   ```
   For the source search, **use jcodemunch** (`search_text` / `search_symbols`),
   not raw `grep` — grep-guard blocks source greps. Two or more pollers on one
   token = confirmed root cause.

## Fix shape

The fix needs **both halves** — code change alone leaves the backlog stuck:

- **Single-consumer enforcement.** Collapse to exactly one poller per token
  (drop the duplicate cron, or gate concurrent runs behind `flock -n`).
- **Deliberate queue drain.** One-time advance of the offset past the stale
  backlog so the dormant flood can't recur on the next trigger.

## Delivery discipline

- **Batch by risk into separate PRs** when the change set spans security surface,
  cron config, and a one-time data drain — don't ship them as one diff.
- **TDD** the code change: write the failing test (single-consumer / offset-advance
  behavior) before the implementation.
- **Run the pre-mortem skill** before editing security-surface files
  (`scripts/`, auth/control logic, third-party integration) — the discipline hook
  requires it, and it catches TOCTOU/cascade/data-integrity regressions in the
  consumer-locking change.
- **Surface what needs a human at the keyboard** (e.g. confirming inbound works
  under the crontab env after merge) rather than claiming end-to-end verification.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.