Skip to content

fix(transport): isolate incompatible Telegram updates - #171

Merged
iriswolf merged 2 commits into
mainfrom
fix/poison-update-decode-handling
Aug 5, 2026
Merged

fix(transport): isolate incompatible Telegram updates#171
iriswolf merged 2 commits into
mainfrom
fix/poison-update-decode-handling

Conversation

@iriswolf

@iriswolf iriswolf commented Aug 5, 2026

Copy link
Copy Markdown
Member

Problem

A valid Telegram Bot API 10.2 rich-message update used ordered-list type "1", but the generated schema required the invalid literal "one". Long polling then classified the deterministic schema failure as transient and retried the same update forever, blocking all later updates.

Generator correction: IWFTech/TelegramSchemaGenerator#22.

Changes

  • refresh the generated rich-list models without the invalid discriminator;
  • decode getUpdates results one update at a time in the built-in transport path;
  • stop retrying deterministic schema decode failures as transient request failures;
  • add ITelegramUpdateDecodeFailurePolicy with fail-closed Stop and explicit Skip decisions;
  • apply the same policy to syntactically valid webhook updates that do not match the installed schema;
  • preserve malformed webhook payload handling as 400 and direct ITelegramClient.SendAsync(new GetUpdates()) as strict/atomic;
  • log only update id, JSON path, and SHA-256 fingerprint, never the raw update payload;
  • document acknowledgement, cancellation, quarantine, and idempotency semantics in English and Russian.

Touched hot paths

  • TelegramUpdateBatchRequest and TelegramUpdateDecoder: per-element getUpdates decoding. Successful results use a readonly struct carrier; raw JSON and SHA-256 are created only on schema failure.
  • TelegramLongPollingClient: ordered policy decision before offset advancement. Existing handler dispatch and successful-update acknowledgement order remain unchanged.
  • TelegramRawWebhookEndpoint: parse envelope, identify update_id, then apply the shared decode policy. Normal handler execution remains unchanged.

Failure contract

Condition Default result Explicit Skip
Long-poll schema mismatch throw once; do not advance offset acknowledge only after policy completes
Webhook schema mismatch HTTP 500 HTTP 200 only after policy completes
Policy throws or is cancelled no acknowledgement no acknowledgement
Malformed webhook JSON/envelope HTTP 400 policy is not called

Verification

  • Release build: 0 warnings, 0 errors
  • Strict analyzers: passed
  • Fast suite: 863 passed
  • Package smoke: 4 passed
  • Style and whitespace formatting: passed
  • git diff --check: passed

@iriswolf
iriswolf merged commit 5e0e0dd into main Aug 5, 2026
16 checks passed
@iriswolf
iriswolf deleted the fix/poison-update-decode-handling branch August 5, 2026 20:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant