Skip to content

fix(telegram): prevent unlisted API calls from stalling delivery - #104526

Merged
steipete merged 2 commits into
openclaw:mainfrom
arturict:fix/telegram-default-request-timeout-104524
Jul 11, 2026
Merged

steipete merged 2 commits into
openclaw:mainfrom
arturict:fix/telegram-default-request-timeout-104524

Conversation

@arturict

@arturict arturict commented Jul 11, 2026 •

Copy link
Copy Markdown
Contributor

Closes #104524

AI-assisted: yes. I used an OpenAI coding agent, reviewed the resulting change, and understand the timeout behavior.

What Problem This Solves

Fixes an issue where Telegram users could have all outbound replies for a session stall for roughly eight minutes when an API call used a method that was not explicitly listed in the client timeout table.

Why This Change Was Made

Every identified Telegram API method except getUpdates now receives the existing 60-second outbound timeout as a default. Explicit method-specific guards remain unchanged, higher configured timeouts are still honored, and requests whose method cannot be identified remain untouched.

User Impact

A newly introduced or otherwise unlisted Telegram API method can no longer silently fall back to grammY's approximately 500-second timeout and park the serialized delivery lane. Its client-side guard defaults to 60 seconds unless the operator configured a higher timeout.

Evidence

  • pnpm exec vitest run extensions/telegram/src/request-timeouts.test.ts — 1 file, 15 tests passed.
  • pnpm test:extension telegram — 142 files, 2,666 tests passed.
  • pnpm exec oxlint --tsconfig config/tsconfig/oxlint.extensions.json extensions/telegram/src/request-timeouts.ts extensions/telegram/src/request-timeouts.test.ts — 0 warnings, 0 errors.
  • pnpm exec oxfmt --check --threads=1 extensions/telegram/src/request-timeouts.ts extensions/telegram/src/request-timeouts.test.ts — formatting passed.
  • NODE_OPTIONS='--max-old-space-size=2300' node scripts/run-tsgo.mjs -p extensions/telegram/tsconfig.json --noEmit — passed.
  • git diff --check — passed.

No live Telegram probe was run because this checkout has no test-bot credentials. The linked issue includes the production incident evidence and reports the same fallback behavior running in production.

Controlled runtime proof

A credential-free controlled Bot API endpoint exercised the real createTelegramClientFetch and AbortController path on this PR branch. All three requests ran concurrently against delayed local HTTP responses; no Telegram token or external API was used.

controlled_endpoint=http://127.0.0.1:<redacted>/bot<redacted>/METHOD
unlisted-default: answerCallbackQuery, server delay 65000ms -> aborted after 60004ms: Telegram answercallbackquery timed out after 60000ms
unlisted-configured-override: answerCallbackQuery, configured timeout 70s, server delay 62000ms -> HTTP 200 after 62030ms
getUpdates-unchanged: getUpdates, configured timeout 70s, server delay 65000ms -> aborted after 45015ms: Telegram getupdates timed out after 45000ms
proof_result=PASS

This demonstrates the 60-second fallback through the actual fetch wrapper, the existing higher configured-timeout escape hatch, and the unchanged 45-second getUpdates guard.

@openclaw-barnacle openclaw-barnacle Bot added channel: telegram Channel integration: telegram size: XS labels Jul 11, 2026
@arturict
arturict force-pushed the fix/telegram-default-request-timeout-104524 branch from f0ec321 to ecef499 Compare July 11, 2026 14:58
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. labels Jul 11, 2026
@clawsweeper

clawsweeper Bot commented Jul 11, 2026 •

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 11, 2026, 7:25 PM ET / 23:25 UTC.

Summary
The PR makes identified Telegram Bot API methods absent from the explicit timeout table use a 60-second default guard while preserving fixed method limits, the 45-second getUpdates guard, and higher configured timeouts.

PR surface: Source +1, Tests +8. Total +9 across 3 files.

Reproducibility: yes. Current-main source deterministically returns no OpenClaw timer for an active unlisted method, grammY 1.44.0 supplies the documented 500-second fallback, and the linked issue supplies production incident evidence.

Review metrics: 1 noteworthy metric.

  • Timeout fallback defaults: 1 default changed. Every identified Bot API method absent from the explicit table moves from grammY's 500-second dependency fallback to OpenClaw's 60-second guard unless configured higher.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #104524
Summary: This PR is the direct focused candidate fix for the linked production timeout incident.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🦞 diamond lobster
Proof: 🦞 diamond lobster
Patch quality: 🦞 diamond lobster
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Risk before merge

  • [P2] Existing custom Bot API operations using an identified unlisted method and legitimately taking more than 60 seconds will now abort unless the operator configures the existing higher Telegram timeout.

Maintainer options:

  1. Land the bounded fallback (recommended)
    Merge the focused guard with the existing timeoutSeconds setting as the supported escape hatch for unusually slow custom Bot API operations.
  2. Retain grammY's long fallback
    Pause the PR only if unlisted methods must remain eligible for the dependency's 500-second default despite the documented serialized-delivery stall.

Next step before merge

  • No automated repair is needed; the exact-head patch is correct and should proceed through normal owner review and landing gates.

Security
Cleared: The focused resolver and test changes add no dependency, secret, permission, workflow, package-resolution, download, or executable supply-chain surface.

Review details

Best possible solution:

Keep explicit method-specific limits as overrides over the general 60-second guard, retain the fixed getUpdates behavior, and preserve the existing configurable higher timeout for slow custom Bot API deployments.

Do we have a high-confidence way to reproduce the issue?

Yes. Current-main source deterministically returns no OpenClaw timer for an active unlisted method, grammY 1.44.0 supplies the documented 500-second fallback, and the linked issue supplies production incident evidence.

Is this the best way to solve the issue?

Yes. A default guard with explicit per-method overrides closes the recurring allowlist failure class more maintainably than adding one method after each incident, while preserving a configured higher-timeout escape hatch.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 8fea7f501145.

Label changes

Label changes:

  • add rating: 🦞 diamond lobster: Overall readiness is 🦞 diamond lobster; proof is 🦞 diamond lobster and patch quality is 🦞 diamond lobster.
  • remove rating: 🐚 platinum hermit: Current PR rating is rating: 🦞 diamond lobster, so this older rating label is no longer current.

Label justifications:

  • P1: The linked production incident shows one unbounded Telegram API call can stall serialized outbound delivery for roughly eight minutes.
  • merge-risk: 🚨 compatibility: The new fallback deliberately shortens allowed duration for existing slow unlisted operations, although the existing higher timeout configuration remains available.
  • rating: 🦞 diamond lobster: Overall readiness is 🦞 diamond lobster; proof is 🦞 diamond lobster and patch quality is 🦞 diamond lobster.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR body provides redacted controlled live output from delayed HTTP responses through the actual createTelegramClientFetch and AbortController path, demonstrating the new default, configured override, and unchanged getUpdates guard.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body provides redacted controlled live output from delayed HTTP responses through the actual createTelegramClientFetch and AbortController path, demonstrating the new default, configured override, and unchanged getUpdates guard.
Evidence reviewed

PR surface:

Source +1, Tests +8. Total +9 across 3 files.

View PR surface stats
Area Files Added Removed Net
Source 1 9 8 +1
Tests 2 27 19 +8
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 3 36 27 +9

What I checked:

  • Current-main gap: Current main returns undefined when an identified Telegram method is absent from TELEGRAM_REQUEST_TIMEOUTS_MS, so createTelegramClientFetch does not arm its OpenClaw abort timer for that request. (extensions/telegram/src/request-timeouts.ts:55, 8fea7f501145)
  • Runtime caller: The production client fetch extracts the final URL segment as the method, resolves the per-request timeout, and only installs the AbortController timer when that resolver returns a value. (extensions/telegram/src/client-fetch.ts:131, b3136854f0ed)
  • Proposed implementation: The PR preserves getUpdates as a special fixed guard and turns the timeout table into explicit overrides over a 60-second default for every other identified method. (extensions/telegram/src/request-timeouts.ts:54, 3be29f7d3371)
  • Integration coverage: The latest head exercises both listed sendMessage and previously unlisted answerCallbackQuery through the real createTelegramClientFetch AbortController path, while adjacent tests cover configured extension and unchanged getUpdates behavior. (extensions/telegram/src/bot.fetch-abort.test.ts:119, 3be29f7d3371)
  • Dependency contract: grammY 1.44.0 documents and implements a 500-second default API request timeout, including the slow custom Bot API server use case; OpenClaw's new guard therefore deliberately shortens the fallback unless timeoutSeconds is raised. (extensions/telegram/package.json:10, f5c1a3d4c634)
  • Feature history: GitHub file history shows steipete authored seven recent timeout-policy commits, while obviyus introduced the outbound timeout guard and neeravmakwana introduced the startup timeout foundation. (extensions/telegram/src/request-timeouts.ts:7, 071e7610d6db)

Likely related people:

  • steipete: Authored most recent request-timeout history, is assigned to this PR, and added the exact-head integration proof commit. (role: recent timeout-policy owner and current-head contributor; confidence: high; commits: 3be29f7d3371, d69ee6777d74, 91266fa9288a; files: extensions/telegram/src/request-timeouts.ts, extensions/telegram/src/client-fetch.ts, extensions/telegram/src/bot.fetch-abort.test.ts)
  • obviyus: Authored the commit that established Telegram outbound request guards and the timeout table behavior this PR generalizes. (role: introduced outbound timeout behavior; confidence: high; commits: 071e7610d6db; files: extensions/telegram/src/request-timeouts.ts)
  • neeravmakwana: Authored the earlier startup request-timeout implementation from which the current shared resolver evolved. (role: introduced timeout foundation; confidence: medium; commits: 177e23801bdd; files: extensions/telegram/src/request-timeouts.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (2 earlier review cycles)
  • reviewed 2026-07-11T15:09:13.421Z sha ecef499 :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-11T19:32:53.824Z sha ecef499 :: needs maintainer review before merge. :: none

@arturict

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 11, 2026 •

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 11, 2026
@steipete steipete self-assigned this Jul 11, 2026
@clawsweeper clawsweeper Bot added rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. labels Jul 11, 2026
@steipete
steipete merged commit cc419f8 into openclaw:main Jul 11, 2026
113 of 117 checks passed
@steipete

Copy link
Copy Markdown
Contributor

Merged via squash.

@arturict
arturict deleted the fix/telegram-default-request-timeout-104524 branch July 11, 2026 23:42
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 12, 2026
…nclaw#104526)

* fix(telegram): bound unlisted API requests

* test(telegram): prove unlisted request aborts

---------

Co-authored-by: Peter Steinberger <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: telegram Channel integration: telegram merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P1 High-priority user-facing bug, regression, or broken workflow. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. size: S status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

2 participants