Summary
openclaw message send --channel whatsapp fails with No active WhatsApp Web listener (account: default) even when the gateway is running, WhatsApp is linked, inbound messages are received, and auto-replies send successfully.
Version
2026.3.13 (reproduced on 2026.3.12 as well, update did not fix it)
Symptoms
openclaw message send --channel whatsapp --target ... → GatewayClientRequestError: No active WhatsApp Web listener (account: default)
- Inbound messages arrive correctly
- Auto-replies (via
web-auto-reply module) send correctly — text and files
openclaw channels status --probe shows WhatsApp as connected
openclaw channels capabilities --channel whatsapp shows Probe: unavailable
- The error is consistent across gateway restarts and re-links
Root Cause
Two separate bundle files each define their own listeners = new Map() for the WhatsApp Web active-listener registry (sourced from src/web/active-listener.ts):
auth-profiles-DRjqKE3G.js — defines requireActiveWebListener(), used by the gateway WS tool handler (gateway-cli-CuZs0RlJ.js) when processing send RPC calls
model-selection-CU2b7bN6.js — defines setActiveWebListener(), used by the WhatsApp channel runtime (auth-profiles.runtime-BoPFCfb5.js → web-Cz_8x_nz.js) when the channel starts up
Because these are two distinct Map instances in two different bundle files, the channel registers the listener in model-selection's Map while the WS tool handler looks in auth-profiles's Map — and always finds it empty.
The auto-reply path works because it calls setActiveWebListener and sendMessageWhatsApp from the same bundle (web-Cz_8x_nz.js / model-selection-CU2b7bN6.js), so it never crosses the Map boundary.
Workaround
Patch both files to share a single Map via globalThis:
// In both auth-profiles-DRjqKE3G.js and model-selection-CU2b7bN6.js
// Replace:
const listeners = /* @__PURE__ */ new Map();
// With:
globalThis.__ocWebListeners = globalThis.__ocWebListeners || new Map(); const listeners = globalThis.__ocWebListeners;
After patching and restarting the gateway, both openclaw message send (text and files/PDFs) work correctly.
Expected Fix
Ensure active-listener.ts is only bundled once and shared between the gateway WS handler and the WhatsApp channel runtime, so setActiveWebListener and requireActiveWebListener operate on the same Map instance.
Reproduction Steps
- Install openclaw, configure WhatsApp Web channel
- Start the gateway:
openclaw gateway start
- Link WhatsApp:
openclaw channels login --channel whatsapp
- Verify channel is connected:
openclaw channels status --probe → shows connected
- Try to send:
openclaw message send --channel whatsapp --target +1234567890 --message "test"
- →
GatewayClientRequestError: No active WhatsApp Web listener (account: default)
- Send an inbound message from the linked phone → gateway receives it and auto-replies successfully
Platform
- Linux (Fedora 43, kernel 6.17.7-300.fc43.x86_64)
- Node.js 22.22.1
- openclaw installed via npm global (
pnpm)
Summary
openclaw message send --channel whatsappfails withNo active WhatsApp Web listener (account: default)even when the gateway is running, WhatsApp is linked, inbound messages are received, and auto-replies send successfully.Version
2026.3.13(reproduced on2026.3.12as well, update did not fix it)Symptoms
openclaw message send --channel whatsapp --target ...→GatewayClientRequestError: No active WhatsApp Web listener (account: default)web-auto-replymodule) send correctly — text and filesopenclaw channels status --probeshows WhatsApp asconnectedopenclaw channels capabilities --channel whatsappshowsProbe: unavailableRoot Cause
Two separate bundle files each define their own
listeners = new Map()for the WhatsApp Web active-listener registry (sourced fromsrc/web/active-listener.ts):auth-profiles-DRjqKE3G.js— definesrequireActiveWebListener(), used by the gateway WS tool handler (gateway-cli-CuZs0RlJ.js) when processingsendRPC callsmodel-selection-CU2b7bN6.js— definessetActiveWebListener(), used by the WhatsApp channel runtime (auth-profiles.runtime-BoPFCfb5.js→web-Cz_8x_nz.js) when the channel starts upBecause these are two distinct
Mapinstances in two different bundle files, the channel registers the listener inmodel-selection's Map while the WS tool handler looks inauth-profiles's Map — and always finds it empty.The auto-reply path works because it calls
setActiveWebListenerandsendMessageWhatsAppfrom the same bundle (web-Cz_8x_nz.js/model-selection-CU2b7bN6.js), so it never crosses the Map boundary.Workaround
Patch both files to share a single
MapviaglobalThis:After patching and restarting the gateway, both
openclaw message send(text and files/PDFs) work correctly.Expected Fix
Ensure
active-listener.tsis only bundled once and shared between the gateway WS handler and the WhatsApp channel runtime, sosetActiveWebListenerandrequireActiveWebListeneroperate on the sameMapinstance.Reproduction Steps
openclaw gateway startopenclaw channels login --channel whatsappopenclaw channels status --probe→ showsconnectedopenclaw message send --channel whatsapp --target +1234567890 --message "test"GatewayClientRequestError: No active WhatsApp Web listener (account: default)Platform
pnpm)