fix(whatsapp): convert E.164 chat_id to JID before sending via bridge - #25943
Closed
ByteSide wants to merge 1 commit into
Closed
fix(whatsapp): convert E.164 chat_id to JID before sending via bridge#25943ByteSide wants to merge 1 commit into
ByteSide wants to merge 1 commit into
Conversation
The Baileys-backed bridge in scripts/whatsapp-bridge/bridge.js calls sock.sendMessage(chatId, ...), where chatId must be a JID such as '15551234567@s.whatsapp.net' (DMs), '<digits>@lid', or '<digits>@g.us' (groups). Calling it with a raw E.164 string raises 'JID decode failed' inside Baileys and the bridge returns HTTP 500. _parse_target_ref in tools/send_message_tool.py accepts WhatsApp targets in E.164 form ('whatsapp:+15551234567') and marks them as explicit, with a comment that says 'signal-cli and sms/whatsapp adapters expect E.164 format'. That is correct for signal-cli but not for the Baileys bridge. Symptom: send_message(action='send', target='whatsapp:+15551234567', message='...') returns 'WhatsApp bridge error (500): {"error":"JID decode failed"}'. Reproduces against any inactive WhatsApp contact where the directory listing does not yet contain the recipient and the agent falls back to E.164. Fix: in _send_whatsapp, normalize a leading-'+' digits-only target to '<digits>@s.whatsapp.net' before posting to the bridge. Already formatted JIDs (@s.whatsapp.net, @lid, @g.us) pass through unchanged. Adds tests/tools/test_send_message_tool.py::TestSendWhatsappJidNormalization with four cases: E.164 conversion, JID passthrough, @lid passthrough, group-JID passthrough. Existing TestSendToPlatformWhatsapp continues to pass.
ByteSide
force-pushed
the
skippy/fix-whatsapp-e164-to-jid
branch
from
May 14, 2026 21:01
4d84b85 to
e4d74fd
Compare
Collaborator
Contributor
|
Fixed on main via #50379 (salvage of #8639) — bare WhatsApp phone targets are now normalized to @sgaofen's #8639 was the earliest of this cluster, so it was used as the base and credited first; thanks @ByteSide for independently catching and fixing the same bug. Closing as duplicate. |
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.
What does this PR do?
Make
send_messagework for WhatsApp targets specified in E.164 phone-number form._parse_target_refintools/send_message_tool.pyaccepts a WhatsApp target likewhatsapp:+15551234567, returns the E.164 string unchanged, and marks it as explicit. The accompanying comment claims "signal-cli and sms/whatsapp adapters expect E.164 format" — this is correct for signal-cli, but the Baileys-backed bridge inscripts/whatsapp-bridge/bridge.jscallssock.sendMessage(chatId, ...), wherechatIdmust be a JID (<digits>@s.whatsapp.net,<digits>@lid, or<digits>@g.us). Calling it with a raw E.164 string raisesJID decode failedinside Baileys and the bridge returns HTTP 500.This is reproducible from any agent reply where the recipient is not yet in the directory listing — the agent then falls back to passing the E.164 string straight through.
Why fix it in
_send_whatsapprather than_parse_target_refI deliberately did not change the parser, because
_PHONE_PLATFORMSis shared with Signal/SMS where E.164 is the correct downstream format. Normalizing inside_send_whatsappkeeps the parser invariant intact and the conversion local to the only adapter that needs JIDs. Already-formed JIDs (@s.whatsapp.net,@lid,@g.us) pass through unchanged.Related Issue
Fixes #
Type of Change
Changes Made
tools/send_message_tool.py_send_whatsapp: add a 4-line normalization block before the HTTP POST. Converts leading-+digits-onlychat_idto<digits>@s.whatsapp.net; everything else (including already-formed JIDs) is unchanged.tests/tools/test_send_message_tool.py: newTestSendWhatsappJidNormalizationclass with 4 cases:test_e164_target_is_converted_to_jid—+15551234567→15551234567@s.whatsapp.netin the bridge POST body and in the return value'schat_id.test_already_formed_jid_passes_through—15551234567@s.whatsapp.netunchanged.test_lid_jid_passes_through—123456789012345@lidunchanged.test_group_jid_passes_through—120363045123456789@g.usunchanged.How to Test
End-to-end reproduction (against any running gateway with the Baileys bridge):
Checklist
fix(whatsapp): …).JID,E.164,whatsapp send_messageopen PRs.pytest tests/tools/test_send_message_tool.py -k whatsapp -qand all tests pass (existing 6 + new 4).Documentation & Housekeeping
_send_whatsappexplains the format mismatch and the reason the conversion lives in the adapter (not the parser).send_messageschema continues to advertisewhatsapp:<phone-or-jid>targets.Screenshots / Logs
Bridge log line that motivated the fix: