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

  1. Verify the channel's api_url resolves to the correct iLink instance and path (the QR endpoint is built from it)
  2. 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
  3. Read the body snippet for the concrete iLink error text before changing anything
  4. 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

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


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/63839843728945f4. Report an issue: GitHub.