fix(whatsapp): normalize chatId to JID before sendMessage - #40182
Closed
travelsim wants to merge 1 commit into
Closed
fix(whatsapp): normalize chatId to JID before sendMessage#40182travelsim wants to merge 1 commit into
travelsim wants to merge 1 commit into
Conversation
Baileys' sendMessage() calls jidDecode() internally, which throws 'Cannot destructure user of jidDecode(...) as it is undefined' when the chatId is not a valid JID. The gateway and `hermes send` legitimately pass URI/E.164 forms like 'whatsapp:+61XXXXXXXXX', '+61XXXXXXXXX', or '61XXXXXXXXX' (especially before the channel directory has been populated by inbound messages), so the bridge crashed with 500 on every outbound send. Add normalizeChatId() to the bridge and wire it into /send, /edit, /send-media, and /typing so any input form is converted to a valid <digits>@s.whatsapp.net JID before reaching Baileys. Already-valid JIDs (with @server suffix) and group/lid/newsletter JIDs pass through unchanged.
tonydwb
approved these changes
Jun 6, 2026
tonydwb
left a comment
There was a problem hiding this comment.
Code Review Summary
Verdict: Approved
This PR fixes a real WhatsApp send failure by normalizing non-JID chatId values (E.164, URI-prefixed, bare digits) before every Baileys sendMessage/sendPresenceUpdate call.
Changes
- Introduced
normalizeChatId(raw)with clear heredoc-style documentation of accepted formats and exit conditions. - Applied uniformly across all four write paths:
/send,/edit,/send-media,/typing. - Non-JID inputs are normalized exactly once per request (
targetJid) and reused for all chunks — no redundant work.
Looks Good
- Handling —
includes('@')short-circuit correctly escapes group (@g.us), LID (@lid), and newsletter (@newsletter) identifiers untouched. - Guard rail —
digits.length < 5returnsrawso Baileys produces a real error rather than a silent misroute; sensible safety net without hiding failures. - Scope — only
/scripts/whatsapp-bridge/bridge.jschanged (33 additions / 6 deletions); no API surface shift, no config changes. - Consistency — every caller path in the file is covered; no path was accidentally skipped.
Reviewed by Hermes Agent
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 @travelsim 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
The WhatsApp bridge at
scripts/whatsapp-bridge/bridge.jscrashes with HTTP 500 on every outboundhermes sendwhen the chatId is a URI/E.164/digits form (e.g.whatsapp:+61XXXXXXXXX,+61XXXXXXXXX, or61XXXXXXXXX). The bridge passes the value straight to Baileys'sock.sendMessage(), which callsjidDecode()internally and throws:This affects every first-time user of the WhatsApp gateway: the channel directory is only populated by inbound messages, so
hermes sendand thehermes acpHTTP path are broken until at least one inbound message arrives.Fix
Add a
normalizeChatId(raw)helper to the bridge and call it on the chatId in the 4 affected HTTP handlers:POST /send— convert to JID before each chunkPOST /edit— convert to JID for both the edit key and the follow-up chunksPOST /send-media— convert beforesendMessagePOST /typing— convert beforesendPresenceUpdateThe normalizer:
@(valid JID, group/lid/newsletter) untouchedwhatsapp:URI scheme+${digits}@s.whatsapp.net(gives up and returns the original on fewer than 5 digits, letting Baileys' own error path fire)Tested
POST /sendwith{chatId: 'whatsapp:+61XXXXXXXXX', message: '...'}returns{success:true, messageId:'3EB07...'}(delivered to the user's phone).POST /sendwith already-valid JIDs still works.POST /sendwith malformed inputs (< 5 digits) falls through to the original error path.POST /typingandPOST /editandPOST /send-mediaalso use the normalizer.Context
This is a 33-line / 5-call-site change in one file. No new dependencies, no API changes for the gateway, no behavior change for already-valid JIDs. The bridge is a separate process from the gateway; restarting the bridge loads the new code.