{"record":{"id":"6a416018ed07b4a4","repo":"BigPizzaV3/CodexPlusPlus","slug":"error-6a4160","errorCode":null,"errorMessage":"微信二维码响应缺少必要字段","messagePattern":"微信二维码响应缺少必要字段","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/codex-plus-core/src/connect/weixin.rs","lineNumber":161,"sourceCode":"        let client = Self::new(base_url, \"\", route_tag)?;\n        let mut url = client.endpoint(\"ilink/bot/get_bot_qrcode\")?;\n        url.query_pairs_mut().append_pair(\"bot_type\", \"3\");\n        let response = client\n            .client\n            .get(url)\n            .headers(client.route_headers(false)?)\n            .timeout(Duration::from_secs(40))\n            .send()\n            .await\n            .context(\"获取微信登录二维码失败\")?;\n        let (status, bytes) =\n            read_response_limited(response, MAX_SMALL_RESPONSE_BYTES, \"微信二维码\").await?;\n        if !status.is_success() {\n            bail!(\"获取微信登录二维码失败：HTTP {status}\");\n        }\n        let qr: WeixinQrCode = serde_json::from_slice(&bytes).context(\"微信二维码响应格式无效\")?;\n        if qr.qr_code.trim().is_empty() || qr.qr_content.trim().is_empty() {\n            bail!(\"微信二维码响应缺少必要字段\");\n        }\n        Ok(qr)\n    }\n\n    pub async fn poll_qr_status(\n        base_url: &str,\n        route_tag: &str,\n        qr_code: &str,\n    ) -> anyhow::Result<WeixinQrStatus> {\n        let client = Self::new(base_url, \"\", route_tag)?;\n        let mut url = client.endpoint(\"ilink/bot/get_qrcode_status\")?;\n        url.query_pairs_mut().append_pair(\"qrcode\", qr_code);\n        let response = client\n            .client\n            .get(url)\n            .headers(client.route_headers(true)?)\n            .timeout(Duration::from_secs(40))\n            .send()","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/f2074595a281bc057525c748175c8eb9805b0673/crates/codex-plus-core/src/connect/weixin.rs#L143-L179","documentation":"The QR endpoint returned 2xx and the body parsed as JSON, but qr_code or qr_content came back empty or whitespace, so there is nothing to render or poll. The library refuses rather than showing a blank code; parse failures raise a separate format error.","triggerScenarios":"The gateway returns a well-formed 200 with empty fields: service degraded, the bot is not provisioned for the route tag, or an API contract change renamed the fields.","commonSituations":"ilink maintenance windows; a new bot not yet activated; version mismatch between manager and gateway.","solutions":["Retry fetching a fresh QR code, transient provisioning lag often clears","Confirm route_tag and bot_type match a provisioned bot","Update codex-plus-manager if the field contract changed"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"let qr = match WeixinClient::fetch_qr_code(&base, &tag).await {\n    Ok(qr) => qr,\n    Err(e) if e.to_string().contains(\"缺少必要字段\") => {\n        // empty payload: fetch a fresh code rather than rendering blank\n        WeixinClient::fetch_qr_code(&base, &tag).await?\n    }\n    Err(e) => return Err(e),\n};","preventionTips":["Treat empty QR payloads as retryable provisioning lag","Alert after repeated empty responses, it signals a contract change","Pin gateway-compatible manager versions"],"tags":["weixin","qr-code","schema","empty-response"],"backgroundTag":"api-response-missing-field","analyzedSha":"f2074595a281bc057525c748175c8eb9805b0673","analyzedAt":"2026-08-23T12:52:24.489Z","contentChangedAt":"2026-08-23T12:52:24.489Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}