HKUDS/Vibe-Trading · critical · RuntimeError
Failed to get QR code from WeChat API: {data}
Error message
Failed to get QR code from WeChat API: {data} What it means
Thrown when the WeChat iLink login API response for a QR-code request contains an empty 'qrcode' field. The library calls the bot_type=3 QR endpoint unauthenticated and expects data.qrcode to be a non-empty ticket string; an empty value means the server did not issue a login QR code, and the full response is embedded for diagnosis.
Source
Thrown at agent/src/channels/weixin.py:337
resp = await self._client.post(url, json=payload, headers=self._make_headers(auth=auth))
resp.raise_for_status()
return resp.json()
# ------------------------------------------------------------------
# QR Code Login (matches login-qr.ts)
# ------------------------------------------------------------------
async def _fetch_qr_code(self) -> tuple[str, str]:
"""Fetch a fresh QR code. Returns (qrcode_id, scan_url)."""
data = await self._api_get(
"ilink/bot/get_bot_qrcode",
params={"bot_type": "3"},
auth=False,
)
qrcode_img_content = data.get("qrcode_img_content", "")
qrcode_id = data.get("qrcode", "")
if not qrcode_id:
raise RuntimeError(f"Failed to get QR code from WeChat API: {data}")
return qrcode_id, (qrcode_img_content or qrcode_id)
async def _qr_login(self) -> bool:
"""Perform QR code login flow. Returns True on success."""
try:
refresh_count = 0
qrcode_id, scan_url = await self._fetch_qr_code()
self._print_qr_code(scan_url)
current_poll_base_url = self.config.base_url
while self._running:
try:
status_data = await self._api_get_with_base(
base_url=current_poll_base_url,
endpoint="ilink/bot/get_qrcode_status",
params={"qrcode": qrcode_id},
auth=False,
)View on GitHub (pinned to 80ffdda44c)
Solutions
- Retry the QR login after a short backoff (30-60s); transient server refusals are common.
- Inspect the full response dict in the message: if it is empty/HTML, check network proxy or DNS interception.
- Verify the request parameters (bot_type='3', auth=False) match the API version your account/backend supports.
- Check WeChat service status and confirm the account is not temporarily blocked from iLink bot login.
Example fix
// before
qrcode_id, img = await self._fetch_qr_code()
// after
for attempt in range(3):
try:
qrcode_id, img = await self._fetch_qr_code()
break
except RuntimeError:
if attempt == 2: raise
await asyncio.sleep(30) Defensive patterns
Strategy: retry
Try / catch
try:
qrcode_id, img = await channel._fetch_qr_code()
except RuntimeError as e:
if "Failed to get QR code" in str(e):
await asyncio.sleep(30) # then retry, max N times
else:
raise Prevention
- Retry QR issuance with 30-60s backoff.
- Avoid rapid repeated logins (rate limiting).
- Log the full API response embedded in the exception.
When it happens
Trigger: Calling _fetch_qr_code (via _qr_login) where the POST to the WeChat API returns JSON lacking or with an empty 'qrcode' key — e.g. server-side rate limiting, service outage, changed response schema, or invalid bot_type parameter.
Common situations: Frequent re-logins triggering WeChat rate limits; WeChat iLink API schema changes after a server update; network middleboxes returning an HTML error page parsed as empty data; misconfigured bot credentials causing the server to refuse QR issuance.
Related errors
- getUpdates failed: ret={ret} errcode={errcode} errmsg={data.
- WeChat client not initialized or not authenticated
- WeChat send text error (ret={ret}, errcode={errcode}): {data
- getuploadurl returned no upload URL (need upload_full_url or
- WeChat send media error (ret={ret}, errcode={errcode}): {dat
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/4f5e75625b5f4ded.
Report an issue: GitHub.