{"record":{"id":"43baa2182c21b1a7","repo":"BigPizzaV3/CodexPlusPlus","slug":"label","errorCode":null,"errorMessage":"{label}超过大小限制","messagePattern":"(.+?)超过大小限制","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/codex-plus-core/src/connect/weixin.rs","lineNumber":370,"sourceCode":"        .render::<qrcode::render::svg::Color>()\n        .min_dimensions(320, 320)\n        .dark_color(qrcode::render::svg::Color(\"#111827\"))\n        .light_color(qrcode::render::svg::Color(\"#ffffff\"))\n        .build())\n}\n\nasync fn read_response_limited(\n    response: reqwest::Response,\n    max_bytes: usize,\n    label: &str,\n) -> anyhow::Result<(reqwest::StatusCode, Vec<u8>)> {\n    let status = response.status();\n    let mut stream = response.bytes_stream();\n    let mut bytes = Vec::new();\n    while let Some(chunk) = stream.next().await {\n        let chunk = chunk.with_context(|| format!(\"读取{label}失败\"))?;\n        if bytes.len().saturating_add(chunk.len()) > max_bytes {\n            bail!(\"{label}超过大小限制\");\n        }\n        bytes.extend_from_slice(&chunk);\n    }\n    Ok((status, bytes))\n}\n\nimpl WeixinMessage {\n    pub fn is_finished_user_message(&self) -> bool {\n        self.message_type == 1 && self.message_state == 2 && !self.from_user_id.trim().is_empty()\n    }\n\n    pub fn text(&self) -> Option<String> {\n        self.item_list.iter().find_map(message_item_text)\n    }\n\n    pub fn dedup_key(&self) -> String {\n        format!(\n            \"{}|{}|{}|{}|{}\",","sourceCodeStart":352,"sourceCodeEnd":388,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/f2074595a281bc057525c748175c8eb9805b0673/crates/codex-plus-core/src/connect/weixin.rs#L352-L388","documentation":"read_response_limited streams the HTTP body and hard-caps it at a caller-supplied max_bytes (1 MiB for send_text via MAX_SMALL_RESPONSE_BYTES, 64 MiB for the polling paths via MAX_API_RESPONSE_BYTES). When cumulative bytes exceed the cap it bails with '{label}超过大小限制'. It is a deliberate memory guard against unbounded responses.","triggerScenarios":"The send endpoint returning more than 1 MiB (for example an HTML error or captive-portal page because base_url is wrong); get_updates returning a message backlog larger than 64 MiB; an intercepting proxy replacing the API response.","commonSituations":"base_url pointed at a proxy or antivirus gateway that injects large pages; infrequent polling letting the longpoll backlog grow; captive enterprise or hotel networks intercepting the connection.","solutions":["Verify base_url points at the genuine WeChat ilink API origin with no intercepting proxy","Poll more frequently so the pending message buffer stays far below 64 MiB","Treat as transient: re-poll once after a short backoff; if it recurs at the same step, inspect the actual response with curl -D against the same URL","Do not raise the constants to make it go away - the cap is the memory-safety guard"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"Catch the error from the weixin call and test whether the message ends with '超过大小限制'; the {label} prefix names the endpoint that tripped it. Re-poll once after a delay, then stop and report the label plus the configured base_url - a persistent size failure means the body is not coming from the real API.","preventionTips":["Keep polling cadence high enough that queued messages stay well under 64 MiB","Point base_url directly at the API origin, never through an authenticating proxy","Check for captive-portal conditions before attributing the error to WeChat"],"tags":["response-size-limit","memory-guard","network","rust"],"backgroundTag":"response-size-limit-exceeded","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"}