Skip to content

WhatsApp (Baileys) session repeatedly killed by 401 conflict/device_removed — Chatwoot itself appears to be causing it #577

Description

@DrWallx

Summary

Chatwoot itself appears to be the one disconnecting our WhatsApp number, not WhatsApp acting on its own or a human interfering. Our WhatsApp connection (Baileys channel, self-hosted ghcr.io/fazer-ai/baileys-api:latest, paired to Chatwoot) has been disconnecting repeatedly over the last several days, requiring a manual QR re-scan each time — this is a real production number for a medical clinic, so every disconnect means the AI agent stops receiving/replying to patients until someone notices and re-scans. We only have one person with access to the phone/QR — nobody else has scanned a QR or logged into WhatsApp Web/Desktop for this number elsewhere, so this isn't a "someone else logged in" case.

Our leading theory (details below) is that a periodic "ensure connection" call Chatwoot makes to the Baileys API every ~5 minutes, 24/7, is not fully idempotent and is itself what's causing WhatsApp to see a conflicting login and kill the session. We'd like help confirming or ruling this out.

What we found in the Baileys logs (last 96h)

Three distinct disconnect patterns:

  1. statusCode=428 "Connection Terminated" — frequent, self-heals via auto-reconnect. Presumably normal network blips.
  2. statusCode=503 "Stream Errored (unknown)" — occasional, self-heals via auto-reconnect.
  3. statusCode=515 "Stream Errored (restart required)" — happens right after a fresh QR pairing, self-heals.
  4. statusCode=401 with reasonNode: {"tag":"conflict","attrs":{"type":"device_removed"}} — this is the one that actually kills the session and requires a manual QR re-scan. It happened 3 times in 4 days (including once on our production launch day).

Example log line for #4:

{"level":50,"reasonNode":{"tag":"conflict","attrs":{"type":"device_removed"}},"fullErrorNode":{"tag":"stream:error","attrs":{"code":"401"},"content":[{"tag":"conflict","attrs":{"type":"device_removed"}}]},"msg":"stream errored out"}

What we ruled out

  • No other person has access to the phone or has scanned a QR/logged into WhatsApp Web elsewhere for this number.
  • Only one baileys-api container exists for this number (no duplicate/orphaned instance).
  • The baileys-api container itself never restarted/crashed (RestartCount: 0, no OOM, low CPU/mem usage) — this isn't a resource or infra problem on our end.

One suspicious pattern we noticed

We see a POST /connections/{number} call (the "ensure connection" endpoint) firing roughly every 5 minutes, continuously, 24/7 — ~1050 times over 96h. We couldn't confirm from our side whether this call is fully idempotent when the connection is already healthy (i.e., whether it might occasionally re-trigger some form of re-authentication instead of a pure no-op check), since this appears to originate from the Chatwoot side (custom chatwoot-pro fork), not from agents-pro. If it isn't perfectly idempotent, that frequency seems like a plausible way to eventually trip WhatsApp's own multi-device conflict detection.

Question

Is the device_removed conflict a known failure mode? Is the ~5min "ensure connection" polling from Chatwoot's side expected/safe, or could it be a contributing factor? Any guidance on reducing this rate or making it a true no-op when the session is already open would help — this is a real production WhatsApp number for a medical clinic (Haux Life), so unnecessary reconnects carry real risk of WhatsApp treating the account as automated/abusive.

Happy to share more targeted logs if useful.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs triageNot yet triaged: no type and no priority reviewed

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions