Fix deploy-time profile sync: Telegram rejects empty multipart requests - #73
Merged
Conversation
Telegram now answers a bodyless HTTP 400 when a multipart/form-data
request arrives with no fields. The bot library encodes parameterless
methods (getMyName, getMe, getChatMenuButton) exactly that way — a
multipart Content-Type with a zero-byte body — so profile sync failed
deterministically on its first read call in the last three deploys,
misreported as transient. A RoundTripper on cmd/botprofile's HTTP
client rewrites the empty envelope into an application/json {} body,
which Telegram accepts; any request carrying fields passes through
untouched. Runtime services are unaffected: every call they make
carries at least one field.
Verified live against the testing bot: sync now reports
PROFILE_SYNC_STATUS=synchronized and /city appears in the command menu.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Symptom
The last three testing deploys ended with the warning "Telegram profile synchronization remained temporarily unavailable after retries". It looked transient; it wasn't.
Root cause (verified with a raw-transport probe)
multipart/form-data— including parameterless methods (getMyName,getMe,getChatMenuButton), which it sends with a multipart Content-Type and a zero-byte body.application/json{}(verified with curl); the latest library (v1.23.0) still has the bug.Fix
A
RoundTripperin the botprofile adapter rewrites a multipart request whose body is empty (or only a closing boundary) into anapplication/json{}body. Requests carrying any field — including the avatar upload — pass through untouched (≤128-byte guard). Wired only intocmd/botprofile; the runtime services never call parameterless methods (all useWithSkipGetMe, every call has fields).Verified live
Ran
cmd/botprofileagainst the testing bot with this fix:PROFILE_SYNC_STATUS=synchronized(first success in 3 deploys)getMyCommandsnow lists all 12 commands including/citypending: 0,last_error: noneSo the testing bot is already fully synced; merging this makes future deploys stop tripping over it.
Tests
Transport unit tests: bodyless multipart → JSON, closing-boundary-only multipart → JSON, multipart with fields → untouched.
make checkgreen. Triage row inoperations.mdupdated.🤖 Generated with Claude Code