📋 Bug Description
After successfully pairing an instance (Baileys integration) on v2.4.0-rc2, POST /message/sendText/{instance} consistently returns HTTP 500 with the message Cannot read properties of undefined (reading 'textMessage'), even though:
- The schema in
src/validate/message.schema.ts requires text at the top level (which is what we send).
- The controller in
src/api/controllers/sendMessage.controller.ts and the service whatsapp.baileys.service.ts both read data.text from SendTextDto.
chat/whatsappNumbers works correctly on the same instance immediately before the failing call (proves the socket is responsive for queries).
Minutes after the failure, GET /instance/connectionState/{instance} returns {"instance":{"instanceName":"..."}} without the state field — suggesting the Baileys socket silently dropped, even though the device still appears as "linked" on the WhatsApp app on the paired phone.
Sending the payload in the documented nested format {"number":"...","textMessage":{"text":"..."}} returns HTTP 400 instance requires property "text" (schema rejects it). So both shapes fail.
🔄 Steps to Reproduce
- Start
evoapicloud/evolution-api:2.4.0-rc2 with Postgres 16 backend.
- Create an instance with
integration: "WHATSAPP-BAILEYS", proxy fields (IPRoyal ISP residential, HTTP CONNECT), and a webhook.
- Scan the returned QR with a fresh WhatsApp number.
- Confirm pairing on the phone (device appears in "Linked Devices").
GET /instance/connectionState/{name} → {"state":"open"}.
POST /chat/whatsappNumbers/{name} with the destination number → returns {exists:true,jid:...} instantly.
POST /message/sendText/{name} with {"number":"55XX...","text":"hello"} → returns HTTP 500.
- Re-check
connectionState shortly after → no state field in the response.
curl used:
curl -X POST "https://<host>/message/sendText/<instance>" \
-H "Content-Type: application/json" \
-H "apikey: <key>" \
-d '{"number":"5511XXXXXXXXX","text":"hello"}'
### ✅ Expected Behavior
```markdown
`POST /message/sendText` with `{number, text}` payload (matching the schema in `src/validate/message.schema.ts` and the `SendTextDto` consumed by the controller) should send the message and return a `messageSent` response with key/status, as on previous stable versions.
### ❌ Actual Behavior
HTTP 500 response:
```json
{
"status": 500,
"error": "Internal Server Error",
"response": {
"message": "Cannot read properties of undefined (reading 'textMessage')"
}
}
No stack trace appears in the container logs (filtered with LOG_LEVEL=["ERROR","WARN","INFO"]) when grep'd for textMessage. The error is returned by the Express error handler but the original throw site is not visible in the structured logger output.
The instance becomes silently disconnected at the Baileys socket level shortly after (no state field in connectionState), even though the device remains linked on the phone.
### 🌍 Environment
- OS: Debian-based container, host runs Docker on Ubuntu 22.04
- Node.js version: node:20-alpine (bundled in the official image)
- Evolution API version: 2.4.0-rc2 (also reproduced behavior on 2.3.7 with a different failure mode: `Pre-key upload timeout` and `sendText` hangs 30s without returning)
- Database: PostgreSQL 16 (postgres:16-alpine, dedicated, not Supabase)
- Connection type: Baileys (`integration: "WHATSAPP-BAILEYS"`)
- Proxy: IPRoyal ISP residential, HTTP CONNECT, configured per-instance via `proxyHost/proxyPort/proxyUsername/proxyPassword`
- Ingress: Cloudflare Tunnel → Caddy 2.8 → Evolution :8080 (Docker bridge network)
- Env: `CONFIG_SESSION_PHONE_CLIENT=Hermes CRM`, `CONFIG_SESSION_PHONE_NAME=Chrome`, no `CONFIG_SESSION_PHONE_VERSION` set
### 📋 Logs
```shell
(no stack trace visible; container logs filtered with LOG_LEVEL=["ERROR","WARN","INFO"] did not show any line matching "textMessage" around the time of the failing request)
Earlier on v2.3.7 (different version, related path) we saw:
fullErrorNode={"tag":"stream:error","attrs":{"code":"515"}} msg=stream errored out
err={"type":"Error","message":"Pre-key upload timeout","stack":"Error: Pre-key upload timeout\n at Timeout._onTimeout (file:///evolution/node_modules/baileys/lib/Socket/socket.js:390:64)..."}
msg=Failed to check/upload pre-keys during initialization
msg=unexpected error in 'handling notification'
📝 Additional Context
What we tried (matrix of combinations):
| Version |
Phone client |
Phone version |
Proxy |
Result |
| 2.3.7 |
Hermes CRM |
(default) |
IPRoyal |
Paired (state=open), sendText hangs 30s, pre-key timeout in logs |
| 2.3.7 |
Hermes CRM |
(default) |
none |
Same hang, pre-key timeout |
| 2.3.7 |
Hermes CRM |
(default) |
IPRoyal + NODE_OPTIONS=--dns-result-order=ipv4first |
state=open, query works, sendText still hangs |
| 2.4.0-rc2 |
Hermes CRM |
(default) |
IPRoyal |
Paired, sendText 500 textMessage undefined |
| 2.4.0-rc2 |
Chrome |
2.3000.1027934701 |
IPRoyal |
WhatsApp rejects pairing ("could not connect device") |
| 2.4.0-rc2 |
Chrome |
(default) |
IPRoyal |
Connect hangs 20s, QR generation returns empty |
Payload variations on 2.4.0-rc2:
{number, text} → 500 textMessage undefined
{number, textMessage:{text}} → 400 "instance requires property text"
{number, text, textMessage:{text}} → 500 textMessage undefined (same as first)
Questions:
- Where in the v2.4.0-rc2 codebase is
.textMessage accessed on an undefined parent, triggering this 500? Couldn't find it in sendMessage.controller.ts, whatsapp.baileys.service.ts, evolution.channel.service.ts, event.manager.ts, or baileysMessage.processor.ts. Could it be an integration hook (Chatwoot, OpenAI, Typebot, etc.) running by default even when disabled?
- Is there a known-good combination (Evolution version + Baileys version + WA Web
CONFIG_SESSION_PHONE_VERSION + proxy type) running in production today with WHATSAPP-BAILEYS integration?
- Why does
connectionState lose the state field shortly after a successful connect, even when the device remains linked on the phone?
📋 Bug Description
After successfully pairing an instance (Baileys integration) on
v2.4.0-rc2,POST /message/sendText/{instance}consistently returns HTTP 500 with the messageCannot read properties of undefined (reading 'textMessage'), even though:src/validate/message.schema.tsrequirestextat the top level (which is what we send).src/api/controllers/sendMessage.controller.tsand the servicewhatsapp.baileys.service.tsboth readdata.textfromSendTextDto.chat/whatsappNumbersworks correctly on the same instance immediately before the failing call (proves the socket is responsive for queries).Minutes after the failure,
GET /instance/connectionState/{instance}returns{"instance":{"instanceName":"..."}}without thestatefield — suggesting the Baileys socket silently dropped, even though the device still appears as "linked" on the WhatsApp app on the paired phone.Sending the payload in the documented nested format
{"number":"...","textMessage":{"text":"..."}}returns HTTP 400instance requires property "text"(schema rejects it). So both shapes fail.🔄 Steps to Reproduce
evoapicloud/evolution-api:2.4.0-rc2with Postgres 16 backend.integration: "WHATSAPP-BAILEYS", proxy fields (IPRoyal ISP residential, HTTP CONNECT), and a webhook.GET /instance/connectionState/{name}→{"state":"open"}.POST /chat/whatsappNumbers/{name}with the destination number → returns{exists:true,jid:...}instantly.POST /message/sendText/{name}with{"number":"55XX...","text":"hello"}→ returns HTTP 500.connectionStateshortly after → nostatefield in the response.curl used:
📝 Additional Context
What we tried (matrix of combinations):
NODE_OPTIONS=--dns-result-order=ipv4firstPayload variations on 2.4.0-rc2:
{number, text}→ 500 textMessage undefined{number, textMessage:{text}}→ 400 "instance requires property text"{number, text, textMessage:{text}}→ 500 textMessage undefined (same as first)Questions:
.textMessageaccessed on an undefined parent, triggering this 500? Couldn't find it insendMessage.controller.ts,whatsapp.baileys.service.ts,evolution.channel.service.ts,event.manager.ts, orbaileysMessage.processor.ts. Could it be an integration hook (Chatwoot, OpenAI, Typebot, etc.) running by default even when disabled?CONFIG_SESSION_PHONE_VERSION+ proxy type) running in production today withWHATSAPP-BAILEYSintegration?connectionStatelose thestatefield shortly after a successfulconnect, even when the device remains linked on the phone?