{"record":{"id":"fb79ea3839ff8194","repo":"zeroclaw-labs/zeroclaw","slug":"wecom-max-file-size-bytes-is-zero","errorCode":null,"errorMessage":"WeCom max_file_size_bytes is zero","messagePattern":"WeCom max_file_size_bytes is zero","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-channels/src/wecom_ws.rs","lineNumber":1285,"sourceCode":"            other => {\n                wecom_log_info!(\n                    \"[wecom_ws] unsupported msg_type={other}, raw_payload={}\",\n                    inbound.raw_payload\n                );\n                NormalizedMessage::Unsupported\n            }\n        }\n    }\n\n    async fn download_and_store_attachment(\n        &self,\n        url: &str,\n        kind: AttachmentKind,\n        inbound: &ParsedInbound,\n        aeskey: Option<&str>,\n    ) -> Result<String> {\n        if self.cfg.max_file_size_bytes == 0 {\n            anyhow::bail!(\"WeCom max_file_size_bytes is zero\");\n        }\n\n        let started = Instant::now();\n        let chat_id = inbound.chat_id.as_deref().unwrap_or(\"single\");\n        let url_target = summarize_attachment_url_for_log(url);\n        wecom_log_info!(\n            \"WeCom attachment download started msg_id={} msg_type={} chat_type={} chat_id={} sender_userid={} attachment_kind={} url_target={} has_aeskey={} timeout_secs={}\",\n            inbound.msg_id,\n            inbound.msg_type,\n            inbound.chat_type,\n            chat_id,\n            inbound.sender_userid,\n            kind.as_str(),\n            url_target,\n            aeskey.is_some(),\n            WECOM_HTTP_TIMEOUT_SECS\n        );\n","sourceCodeStart":1267,"sourceCodeEnd":1303,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-channels/src/wecom_ws.rs#L1267-L1303","documentation":"WeCom WS attachment handling compares downloaded size against cfg.max_file_size_bytes; a zero limit would make the check meaningless, so download_and_store_attachment refuses to run and bails immediately. It is a config sanity guard tripped on the first inbound attachment after startup.","triggerScenarios":"wecom_ws channel configured with max_file_size_bytes unset or 0 (bad TOML default, typo'd key, or 0 intended to mean 'unlimited') and any inbound message with media arrives.","commonSituations":"Users set 0 expecting 'no limit'; a config migration dropped the key; templates ship a placeholder 0; the key name was renamed and the old key silently ignored.","solutions":["Set max_file_size_bytes to an explicit positive limit (e.g. 10485760 = 10 MB) in the wecom_ws channel config","Size the limit against WeCom media constraints and local disk budget","Reload/restart the channel after the config change"],"exampleFix":"# before\n[channels.wecom_ws]\nmax_file_size_bytes = 0\n# after\n[channels.wecom_ws]\nmax_file_size_bytes = 10485760","handlingStrategy":"validation","validationCode":"fn wecom_file_limit_ok(limit: u64) -> bool { limit > 0 }\nif !wecom_file_limit_ok(cfg.max_file_size_bytes) {\n    return Err(anyhow::anyhow!(\n        \"max_file_size_bytes must be > 0 (got 0)\"\n    ));\n}","typeGuard":null,"tryCatchPattern":"Treat as a startup config error: validate before enabling the channel so the first inbound attachment does not discover it.","preventionTips":["Document that 0 is not a valid 'unlimited' sentinel for this channel","Validate required numeric config keys at load time with nonzero checks","Give config templates a real default limit so the key is never accidentally 0"],"tags":["wecom","config","attachment","validation","size-limit"],"backgroundTag":"invalid-config-value","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}