BigPizzaV3/CodexPlusPlus · error · anyhow::Error

微信长轮询被拒绝:ret={} errcode={} {}

Error message

微信长轮询被拒绝:ret={} errcode={} {}

What it means

The long poll returned 2xx with valid JSON, but the body reports a business-level error: ret is nonzero or errcode is nonzero, with errmsg. This is WeChat-side rejection at the application layer, such as an expired or invalidated token, a session kicked by another login, or a channel_version the gateway no longer accepts, not a transport failure.

Source

Thrown at crates/codex-plus-core/src/connect/weixin.rs:239

                    ret: 0,
                    errcode: 0,
                    errmsg: String::new(),
                    messages: Vec::new(),
                    get_updates_buf: get_updates_buf.to_string(),
                    longpolling_timeout_ms: timeout_ms,
                });
            }
            Err(error) => return Err(error).context("微信长轮询请求失败"),
        };
        let (http_status, bytes) =
            read_response_limited(response, MAX_API_RESPONSE_BYTES, "微信长轮询").await?;
        if !http_status.is_success() {
            bail!("微信长轮询请求失败:HTTP {http_status}");
        }
        let updates: WeixinUpdates =
            serde_json::from_slice(&bytes).context("微信长轮询响应格式无效")?;
        if updates.ret != 0 || updates.errcode != 0 {
            bail!(
                "微信长轮询被拒绝:ret={} errcode={} {}",
                updates.ret,
                updates.errcode,
                updates.errmsg
            );
        }
        Ok(updates)
    }

    pub async fn send_text_chunks(
        &self,
        to_user_id: &str,
        text: &str,
        context_token: &str,
    ) -> anyhow::Result<()> {
        if context_token.trim().is_empty() {
            bail!("微信回复缺少 context_token");
        }

View on GitHub (pinned to f2074595a2)

Solutions

  1. Re-authenticate by scanning a fresh QR code to obtain a new token
  2. Run only one connector instance per account at a time
  3. Update codex-plus-manager so CHANNEL_VERSION matches what the gateway accepts
  4. Decode ret and errcode from the message to confirm the rejection reason
Defensive patterns

Strategy: try-catch

Try / catch

match client.get_updates(&buf, timeout_ms).await {
    Ok(u) => u,
    Err(e) => {
        let text = e.to_string();
        if text.contains("ret=") || text.contains("errcode=") {
            start_relogin_flow().await?; // token-level rejection, re-scan QR
            continue;
        }
        return Err(e);
    }
}

Prevention

When it happens

Trigger: get_updates with a token that was invalidated, for example the QR was scanned on another device; the account logged out; CHANNEL_VERSION in the request no longer accepted after a gateway update.

Common situations: Two connectors using the same account; WeChat kicked the bot session; gateway update requiring a newer client version.

Related errors


AI-assisted analysis of BigPizzaV3/CodexPlusPlus@f2074595a2 (2026-08-23). Data as JSON: /api/errors/8f7441054af67008. Report an issue: GitHub.