zeroclaw-labs/zeroclaw · error · anyhow::Error
WeChat QR code fetch failed ({$status}): {$body}
Error message
WeChat QR code fetch failed ({$status}): {$body} What it means
The QR-fetch step of WeChat login does GET {api_url}/get_bot_qrcode?bot_type=3; a non-2xx response bails with this message, formatted through the cli-wechat-qr-fetch-status-failed i18n key with the HTTP status and body. It is the transport-level failure of obtaining the QR image before login polling begins.
Source
Thrown at crates/zeroclaw-channels/src/wechat.rs:1661
"WeChat QR login gave up after repeated expiry",
);
anyhow::bail!("{reason}");
}
// Fetch QR code
let qr_url = format!("{}?bot_type=3", self.api_url("get_bot_qrcode"));
let resp = self
.client
.get(&qr_url)
.timeout(API_TIMEOUT)
.send()
.await
.with_context(|| wechat_cli_string("cli-wechat-qr-fetch-failed"))?;
if !resp.status().is_success() {
let status = resp.status().to_string();
let body = resp.text().await.unwrap_or_default();
anyhow::bail!(
"{}",
wechat_cli_string_with_args(
"cli-wechat-qr-fetch-status-failed",
&[("status", &status), ("body", &body)],
)
);
}
let qr_data: serde_json::Value = resp.json().await?;
let qrcode = qr_data
.get("qrcode")
.and_then(|v| v.as_str())
.with_context(|| {
wechat_cli_string_with_args(
"cli-wechat-missing-response-field",
&[("field", "qrcode")],
)
})?View on GitHub (pinned to 88bb9c8533)
Solutions
- Verify the channel's api_url resolves to the correct iLink instance and path (the QR endpoint is built from it)
- Act on the embedded status: 401/403 → fix the iLink token; 404 → wrong endpoint/path in api_url; 5xx → retry later once the service is healthy
- Read the body snippet for the concrete iLink error text before changing anything
- Retry login after fixing the underlying cause
Example fix
# before [channels.wechat] api_url = "https://ilink.example" # after [channels.wechat] api_url = "https://ilink.example.com/api/"
Defensive patterns
Strategy: retry
Validate before calling
// Pre-flight the QR endpoint before entering the login loop
let probe = reqwest::Client::new()
.get(format!("{api_url}/get_bot_qrcode?bot_type=3"))
.send().await?;
if !probe.status().is_success() {
return Err(anyhow::anyhow!("fix api_url/token before login"));
} Try / catch
Branch on the embedded status: 401/403/404 are config errors — stop and fix api_url/token, do not loop; 5xx are transient — retry login with backoff after the service recovers.
Prevention
- Validate api_url and the iLink token with a cheap health call before enabling the channel
- Monitor iLink availability; gate login attempts on it
- Wrap login in a bounded retry so a single 5xx does not kill the channel
When it happens
Trigger: Calling login() when the iLink get_bot_qrcode endpoint returns 401/403 (bad token), 404 (wrong api_url or path), 500/502 (iLink outage), or a proxy error page.
Common situations: Channel config pointing at the wrong iLink base URL or missing a path prefix; expired or invalid iLink API token; iLink service down or restarting; a corporate proxy intercepting the request.
Related errors
- OpenAI TTS API error ({}): {}
- QR payload is empty
- getUploadUrl failed ({status}): {body}
- WeChat QR code expired {$max} times, giving up.
- sendMessage failed ({status}): {err}
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/63839843728945f4.
Report an issue: GitHub.