Skip to content

fix(telegram): isolate update offset state by bot token#22363

Closed
AIflow-Labs wants to merge 1 commit intoopenclaw:mainfrom
AIflow-Labs:codex/22300-telegram-polling-consumed
Closed

fix(telegram): isolate update offset state by bot token#22363
AIflow-Labs wants to merge 1 commit intoopenclaw:mainfrom
AIflow-Labs:codex/22300-telegram-polling-consumed

Conversation

@AIflow-Labs
Copy link
Copy Markdown

@AIflow-Labs AIflow-Labs commented Feb 21, 2026

Summary

  • Scope update state writes/reads to include Telegram bot token fingerprinting in src/telegram/update-offset-store.ts and pass token from polling monitor.
  • Added migration-safe behavior: legacy/untagged v1 state files are ignored whenever a token is provided to avoid cross-token offset reuse.
  • Added regression tests covering token-isolated offsets and legacy v1 compatibility guards in src/telegram/update-offset-store.test.ts.

Why this fixes #22300

The previous storage format only keyed offsets by account id, so multiple Telegram tokens/accounts could reuse stale updateId checkpoints and skip messages. Binding checkpoints to token fingerprint prevents cross-token interference while preserving existing file location and cleanup behavior.

Tests

  • pnpm vitest run src/telegram/update-offset-store.test.ts src/telegram/monitor.test.ts
  • pnpm test:fast src/telegram/update-offset-store.test.ts src/telegram/monitor.test.ts

Edge cases

  • If readTelegramUpdateOffset is called with token but stored file is legacy v1 (no fingerprint), it returns null and monitoring starts from fresh state.
  • If token is omitted, behavior remains backward compatible with a single stored offset for that state path (legacy callers).

Greptile Summary

This PR correctly solves cross-token update offset interference by introducing SHA-256 token fingerprinting in the Telegram polling state. The implementation migrates from V1 (account-scoped only) to V2 (account + token scoped) storage format.

Key changes:

  • update-offset-store.ts bumped to version 2, added tokenFingerprint field and validation
  • monitor.ts now passes token to read/write operations (lines 124, 135)
  • Legacy V1 state files are rejected by version check, forcing fresh start on upgrade
  • Atomic write pattern (write to temp + rename) ensures consistency

Migration behavior:
Users upgrading from V1 will have their existing offset files ignored, causing bots to start from fresh state. This is intentional to prevent cross-token contamination when V1 files lack fingerprints.

Test coverage:

  • Token isolation verified (lines 56-71 in test file)
  • V1 rejection tested (lines 73-90)
  • Existing tests for no-token path continue to pass

Note on review comments:
Please disregard the inline comment on update-offset-store.ts line 46. That comment incorrectly suggests allowing V1 files to be read without token validation, which would reintroduce the cross-token offset bug this PR fixes. The current implementation correctly rejects all V1 files to ensure migration safety.

Confidence Score: 4/5

  • This PR is safe to merge with minor caveats around migration behavior
  • The implementation correctly solves the reported issue using well-established patterns (SHA-256 fingerprinting, atomic writes, version migration). Core logic is sound and test coverage addresses the main scenarios. Score reduced from 5 to 4 due to: (1) V1 migration causes users to lose existing offsets (acceptable but worth noting in release notes), and (2) one incorrect review comment was created during analysis that should be disregarded
  • No files require special attention - all three changed files implement the solution correctly

Last reviewed commit: de0df5b

@openclaw-barnacle openclaw-barnacle bot added channel: telegram Channel integration: telegram size: S labels Feb 21, 2026
Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines +46 to 47
if (!parsed || parsed.version !== STORE_VERSION) {
return null;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

version check rejects all v1 files regardless of token presence, contradicting the PR description's claim that "If token is omitted, behavior remains backward compatible". existing v1 offset files will be ignored even for legacy callers, potentially causing duplicate message processing on upgrade

Suggested change
if (!parsed || parsed.version !== STORE_VERSION) {
return null;
if (!parsed || (parsed.version !== STORE_VERSION && parsed.version !== 1)) {
return null;
}
// For V1 files, only use them if no token is expected
if (parsed.version === 1) {
return parsed;
}
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/telegram/update-offset-store.ts
Line: 46-47

Comment:
version check rejects all v1 files regardless of token presence, contradicting the PR description's claim that "If token is omitted, behavior remains backward compatible". existing v1 offset files will be ignored even for legacy callers, potentially causing duplicate message processing on upgrade

```suggestion
    if (!parsed || (parsed.version !== STORE_VERSION && parsed.version !== 1)) {
      return null;
    }
    // For V1 files, only use them if no token is expected
    if (parsed.version === 1) {
      return parsed;
    }
```

How can I resolve this? If you propose a fix, please make it concise.

@vincentkoc
Copy link
Copy Markdown
Member

you have been detected be spamming with unwarranted prs and issues and your issues and prs have been automatically closed. please read contributing guide Contributing.md.

@vincentkoc vincentkoc closed this Feb 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: telegram Channel integration: telegram size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Telegram polling consumes messages but never processes them — bot never responds (macOS, Apple Silicon)

3 participants