HKUDS/Vibe-Trading · error · RuntimeError
WhatsApp channel is not connected
Error message
WhatsApp channel is not connected
What it means
Raised by WhatsApp channel send() when self._client is None or the channel's _connected flag is false. It means send() was called before a successful connect() (or after a disconnect event cleared the client). This is a usage-order error, not a network failure.
Source
Thrown at agent/src/channels/whatsapp.py:394
try:
exc = task.exception()
except asyncio.CancelledError:
return
if login_result.done():
return
if exc is not None:
login_result.set_exception(exc)
else:
login_result.set_exception(
RuntimeError("WhatsApp connection ended before login completed")
)
connect_task.add_done_callback(_on_done)
async def send(self, msg: OutboundMessage) -> None:
client = self._client
if client is None or not self._connected:
raise RuntimeError("WhatsApp channel is not connected")
to = self._build_jid(msg.chat_id)
if msg.content:
await client.send_message(to, msg.content)
for media_path in msg.media or []:
await self._send_media(client, to, media_path)
def _build_jid(self, raw: str) -> Any:
api = _load_neonize()
target = raw.strip()
match = _JID_RE.match(_normalize_jid(target))
if not match:
return api.build_jid(target)
user = match.group("user").split(":", 1)[0]
server = match.group("server")
return api.build_jid(user, server)View on GitHub (pinned to 80ffdda44c)
Solutions
- Await connect() and confirm the connected event before sending.
- If this happens mid-run, check the DisconnectedEv handling and re-establish the session before retrying send().
- Buffer outbound messages and flush them once the connected flag is true.
Example fix
# before
await channel.send(msg) # before connect
# after
await channel.connect()
# wait for _connected / connected event
while not channel.is_connected:
await asyncio.sleep(0.5)
await channel.send(msg) Defensive patterns
Strategy: validation
Validate before calling
async def ensure_connected(channel) -> None:
if not getattr(channel, '_connected', False) or getattr(channel, '_client', None) is None:
await channel.connect() Type guard
def is_whatsapp_ready(channel) -> bool:
return channel._client is not None and channel._connected Try / catch
try:
await channel.send(msg)
except RuntimeError as e:
if 'not connected' in str(e):
await channel.connect()
await channel.send(msg)
else:
raise Prevention
- Always await connect() before the first send
- Queue outbound messages and flush on the connected event
- Subscribe to DisconnectedEv to pause sending during outages
When it happens
Trigger: Calling send() before awaiting connect(); calling send() after the DisconnectedEv handler tore down the client; connect task failed via its done-callback but the caller proceeded anyway.
Common situations: Startup races where messages are queued before the WhatsApp session pairs; session dropped (device unlinked, network loss) and outbound messages still flow; reconnect logic not awaited.
Related errors
- WeChat send media error (ret={ret}, errcode={errcode}): {dat
- WhatsApp dependencies not installed. Run: pip install "vibe-
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/1c64c1d72049a9aa.
Report an issue: GitHub.