Skip to content

POST /message/react hangs with sendIQ usync timeout (75s → 500) — likely LID resolution failure #28

@VictorNascimento14

Description

@VictorNascimento14

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

  1. Have a running, connected instance (authenticated, sending/receiving messages normally).
  2. Get a valid whatsapp_message_id from a recent incoming message (confirmed via webhook).
  3. 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

  1. 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)?
  2. Check whatsmeow version — is it pinned to a version that predates Meta's LID protocol changes?
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions