{"record":{"id":"caba6e7c1998daaf","repo":"zeroclaw-labs/zeroclaw","slug":"wecom-channel-requires-the-channel-wecom-feature","errorCode":null,"errorMessage":"WeCom channel requires the `channel-wecom` feature","messagePattern":"WeCom channel requires the `channel-wecom` feature","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-channels/src/orchestrator/mod.rs","lineNumber":9265,"sourceCode":"                .channels\n                .wecom\n                .get(\"default\")\n                .context(\"WeCom channel is not configured\")?;\n            let alias = \"default\".to_string();\n            let peer_resolver: Arc<dyn Fn() -> Vec<String> + Send + Sync> = {\n                let cfg_arc = config_arc.clone();\n                let alias = alias.clone();\n                Arc::new(move || cfg_arc.read().channel_external_peers(\"wecom\", &alias))\n            };\n            Ok(Arc::new(WeComChannel::new(\n                wc.webhook_key.clone(),\n                alias,\n                peer_resolver,\n            )))\n        }\n        #[cfg(not(feature = \"channel-wecom\"))]\n        \"wecom\" => {\n            anyhow::bail!(\"WeCom channel requires the `channel-wecom` feature\");\n        }\n        #[cfg(feature = \"channel-wecom-ws\")]\n        channel_id\n            if channel_id == \"wecom_ws\"\n                || channel_id == \"wecom-ws\"\n                || channel_id.starts_with(\"wecom_ws.\")\n                || channel_id.starts_with(\"wecom-ws.\") =>\n        {\n            let alias = channel_id\n                .split_once('.')\n                .map(|(_, alias)| alias)\n                .unwrap_or(\"default\")\n                .to_string();\n            let wc =\n                config.channels.wecom_ws.get(&alias).with_context(|| {\n                    format!(\"WeCom WebSocket channel '{alias}' is not configured\")\n                })?;\n            let policy_resolver: Arc<dyn Fn() -> WeComWsRuntimePolicy + Send + Sync> = {","sourceCodeStart":9247,"sourceCodeEnd":9283,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-channels/src/orchestrator/mod.rs#L9247-L9283","documentation":"Raised by build_channel_by_id when channel_id = \"wecom\" is requested but the binary was compiled without `channel-wecom`. WeCom (callback/API mode) is a separate feature from `channel-wecom-ws` (WebSocket mode); this specific bail is the plain WeCom arm. The enabled arm wires WeComChannel with alias and peer_resolver; without the feature only the bail exists.","triggerScenarios":"start_channels / build_channel_by_id selecting \"wecom\" (from [channels.wecom] or an agent binding) in a build without the `channel-wecom` feature.","commonSituations":"Default-feature builds (wecom is only in channels-full), or configs that migrated from wecom_ws back to callback mode while the binary only has channel-wecom-ws enabled — the two WeCom modes are independent features and enabling one does not enable the other.","solutions":["Rebuild with cargo build --release --features channel-wecom (add channel-wecom-ws too if you use the WebSocket mode)","Or use --features channels-full which enables both WeCom features","Or remove [channels.wecom] / \"wecom\" bindings from config","Confirm with zeroclaw_channels::listing::is_channel_type_compiled(\"wecom\")"],"exampleFix":"# before\n cargo build --release --features channel-wecom-ws   # callback arm still missing\n\n # after\n cargo build --release --features \"channel-wecom,channel-wecom-ws\"","handlingStrategy":"validation","validationCode":"use zeroclaw_channels::listing::is_channel_type_compiled;\n\nif !is_channel_type_compiled(\"wecom\") {\n    eprintln!(\"rebuild with --features channel-wecom (callback mode) or remove [channels.wecom]\");\n}","typeGuard":"fn wecom_available() -> bool {\n    zeroclaw_channels::listing::is_channel_type_compiled(\"wecom\")\n}","tryCatchPattern":"match build_channel_by_id(&config_arc, \"wecom\") {\n    Ok(ch) => { /* use */ }\n    Err(e) if e.to_string().contains(\"requires the `channel-wecom` feature\") => {\n        // skip; surface rebuild hint in ops logs\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Remember the two WeCom modes are independent features: channel-wecom (callback) vs channel-wecom-ws (WebSocket)","Enable both if the config may reference either id"],"tags":["rust","cargo-features","feature-gate","zeroclaw","channels","wecom"],"backgroundTag":"cargo-feature-not-enabled","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}