POST /message/react hangs with sendIQ usync timeout (75s → 500) due to LID resolution failure
Summary
The POST /message/react endpoint accepts the request, triggers a sendIQ: namespace=usync call internally to resolve the recipient's LID from phone number, and never receives a response from WhatsApp servers. After whatsmeow's 75-second internal timeout, the endpoint returns HTTP 500.
All other endpoints on the same instance work perfectly — text, media, audio, webhook ingestion. Only reactions (outgoing) fail. Incoming reactions via webhook work fine.
Environment
|
|
| Evolution Go version |
0.7.0 (also reproduced on 0.7.0-beta and 0.6.1-beta) |
| Docker image |
evoapicloud/evolution-go:0.7.0 (sha256:931f477db7cf) |
| OS |
AlmaLinux 9 (VPS) |
| Deploy |
Docker Compose + Traefik reverse proxy |
| WhatsApp context |
Real production instance, authenticated, actively receiving/sending other message types |
Steps to Reproduce
- Have a running, connected instance (authenticated, sending/receiving messages normally).
- Get a valid
whatsapp_message_id from a recent incoming message (confirmed via webhook).
- Call the reaction endpoint:
curl -X POST http://localhost:4000/message/react \
-H "Content-Type: application/json" \
-H "apikey: <INSTANCE_API_TOKEN>" \
-d '{
"number": "5585XXXXXXXXX",
"reaction": "👍",
"id": "3AC274851C9DFE69A18D",
"fromMe": false
}'
Expected Behavior
Reaction is sent to WhatsApp within a few seconds, returns HTTP 200 with the reaction payload (like the documented response example).
Actual Behavior
- Connection hangs for ~75 seconds
- Evolution Go logs internal whatsmeow timeout:
[Client WARN] sendIQ: timeout after 1m15s, id=<IQ_ID>
- Endpoint returns HTTP 500 after timeout
- Reaction never arrives at the target WhatsApp
Logs (relevant excerpt)
22:07:07.795 [Client INFO] sendIQ: namespace=usync, id=, timeout=1m15s
22:07:07.795 [Client INFO] sendIQAsyncAndGetData: sending IQ, id=233.109-94, namespace=usync, to=s.whatsapp.net, target=%!s(<nil>)
22:07:07.795 [Client INFO] sendNodeAndGetData: sending IQ frame, id=233.109-94, xmlns=usync
22:07:07.795 [Client INFO] sendNodeAndGetData: frame sent successfully
22:07:07.795 [Client INFO] sendIQAsyncAndGetData: IQ sent successfully, id=233.109-94
22:07:07.795 [Client INFO] sendIQ: waiting for response, id=233.109-94
...
(75 seconds pass with no `receiveResponse` for id=233.109-94)
...
22:13:57.839 [Client WARN] sendIQ: timeout after 1m15s, id=200.231-13
[GIN] 2026/04/17 - 22:13:57 | 500 | 1m15s | ::1 | POST "/message/react"
For comparison, normal messages on the SAME instance during the SAME period succeed without issue:
22:07:10.220 [Client INFO] receiveResponse: found waiter for id=248.52-1305, tag=iq, sending response
2026/04/17 22:13:28 [INFO] webhook sent successfully - url: https://.../msg-ingest, status: 200
Analysis — LID migration likely root cause
The sendIQ with namespace=usync is performing a user/LID lookup (phone → LID resolution). This fails to receive a response from WhatsApp servers. At the same time, incoming messages now arrive with a "LID/WhatsApp JID swap" pattern:
Detected LID/WhatsApp JID swap case - Sender: 122647102902496@lid, SenderAlt: 558188232676@s.whatsapp.net
JID swap completed - New Sender: 558188232676@s.whatsapp.net, New SenderAlt: 122647102902496@lid
This suggests WhatsApp has migrated messaging to the LID (Local IDentifier) system, and usync queries behave differently now. Other endpoints (/send/text, /send/media) work because they do not require pre-resolving LID via usync — they build the remoteJid directly from the number and let whatsmeow's send path handle routing.
The reaction code path apparently performs an explicit usync lookup before sending, which is the step hanging.
Reproducibility
- 100% reproducible on fresh messages (<1 minute old) and on older messages
- Reproducible with both
fromMe: true and fromMe: false
- Reproducible with and without
@s.whatsapp.net suffix on number
- Not specific to any contact — tested with multiple different phone numbers
What works (for reference)
| Endpoint |
Status |
POST /send/text |
✅ Works (same instance, same phones) |
POST /send/media |
✅ Works |
Incoming webhooks (Type: reaction) |
✅ Delivered correctly |
POST /message/markread |
✅ Works |
POST /message/react |
❌ Times out after 75s → 500 |
Suggested Investigation
- Check the reaction handler in
pkg/message/handler/*.go — is there a call like client.GetUserInfo() / client.Store.LIDs.GetLIDForPN() / similar usync-triggering function before client.SendMessage(ReactionMessage)?
- Check whatsmeow version — is it pinned to a version that predates Meta's LID protocol changes?
- Consider falling back to sending the reaction without the usync lookup when
fromMe: false is specified and the id + number are provided by the caller (caller already has the target info).
Impact
Any application that wants bidirectional reaction sync (incoming + outgoing) is blocked. Workaround is storing reactions locally without syncing to WhatsApp.
Reproducer Script
#!/bin/bash
EVO_URL="http://localhost:4000"
API_KEY="<INSTANCE_API_TOKEN>"
NUMBER="5585XXXXXXXXX"
MSG_ID="<VALID_WHATSAPP_MESSAGE_ID>"
time curl -s -X POST "${EVO_URL}/message/react" \
-H "Content-Type: application/json" \
-H "apikey: ${API_KEY}" \
-d "{\"number\":\"${NUMBER}\",\"reaction\":\"👍\",\"id\":\"${MSG_ID}\",\"fromMe\":false}" \
-w "\nHTTP_STATUS: %{http_code}\n"
# Expected output: HTTP_STATUS: 500 after ~75s with sendIQ usync timeout in container logs
Happy to provide additional logs, payloads, or testing as needed.
POST /message/react hangs with
sendIQ usync timeout(75s → 500) due to LID resolution failureSummary
The
POST /message/reactendpoint accepts the request, triggers asendIQ: namespace=usynccall internally to resolve the recipient's LID from phone number, and never receives a response from WhatsApp servers. After whatsmeow's 75-second internal timeout, the endpoint returns HTTP 500.All other endpoints on the same instance work perfectly — text, media, audio, webhook ingestion. Only reactions (outgoing) fail. Incoming reactions via webhook work fine.
Environment
0.7.0(also reproduced on0.7.0-betaand0.6.1-beta)evoapicloud/evolution-go:0.7.0(sha256:931f477db7cf)Steps to Reproduce
whatsapp_message_idfrom a recent incoming message (confirmed via webhook).Expected Behavior
Reaction is sent to WhatsApp within a few seconds, returns HTTP 200 with the reaction payload (like the documented response example).
Actual Behavior
[Client WARN] sendIQ: timeout after 1m15s, id=<IQ_ID>Logs (relevant excerpt)
For comparison, normal messages on the SAME instance during the SAME period succeed without issue:
Analysis — LID migration likely root cause
The
sendIQwithnamespace=usyncis performing a user/LID lookup (phone → LID resolution). This fails to receive a response from WhatsApp servers. At the same time, incoming messages now arrive with a "LID/WhatsApp JID swap" pattern:This suggests WhatsApp has migrated messaging to the LID (Local IDentifier) system, and
usyncqueries behave differently now. Other endpoints (/send/text,/send/media) work because they do not require pre-resolving LID viausync— they build theremoteJiddirectly from thenumberand let whatsmeow's send path handle routing.The reaction code path apparently performs an explicit
usynclookup before sending, which is the step hanging.Reproducibility
fromMe: trueandfromMe: false@s.whatsapp.netsuffix onnumberWhat works (for reference)
POST /send/textPOST /send/mediaType: reaction)POST /message/markreadPOST /message/reactSuggested Investigation
pkg/message/handler/*.go— is there a call likeclient.GetUserInfo()/client.Store.LIDs.GetLIDForPN()/ similar usync-triggering function beforeclient.SendMessage(ReactionMessage)?fromMe: falseis specified and theid+numberare provided by the caller (caller already has the target info).Impact
Any application that wants bidirectional reaction sync (incoming + outgoing) is blocked. Workaround is storing reactions locally without syncing to WhatsApp.
Reproducer Script
Happy to provide additional logs, payloads, or testing as needed.