zeroclaw-labs/zeroclaw · error · anyhow::Error
QQ channel requires the `channel-qq` feature
Error message
QQ channel requires the `channel-qq` feature
What it means
Raised by build_channel_by_id (crates/zeroclaw-channels/src/orchestrator/mod.rs:8889), the channel factory used by start_channels, when the resolved config selects the QQ channel but the zeroclaw-channels crate was compiled without the `channel-qq` Cargo feature. The config schema accepts [channels.qq] unconditionally, so the mismatch surfaces only at runtime: the `#[cfg(not(feature = "channel-qq"))]` arm still matches channel_id "qq" and bails with the exact feature name instead of reporting an unknown channel.
Source
Thrown at crates/zeroclaw-channels/src/orchestrator/mod.rs:9183
.qq
.get("default")
.context("QQ channel is not configured")?;
let alias = "default".to_string();
let peer_resolver: Arc<dyn Fn() -> Vec<String> + Send + Sync> = {
let cfg_arc = config_arc.clone();
let alias = alias.clone();
Arc::new(move || cfg_arc.read().channel_external_peers("qq", &alias))
};
Ok(Arc::new(QQChannel::new(
qq.app_id.clone(),
qq.app_secret.clone(),
alias,
peer_resolver,
)))
}
#[cfg(not(feature = "channel-qq"))]
"qq" => {
anyhow::bail!("QQ channel requires the `channel-qq` feature");
}
"lark" => {
#[cfg(feature = "channel-lark")]
{
let lk = config
.channels
.lark
.get("default")
.context("Lark channel is not configured")?;
let alias = "default".to_string();
let peer_resolver: Arc<dyn Fn() -> Vec<String> + Send + Sync> = {
let cfg_arc = config_arc.clone();
let alias = alias.clone();
Arc::new(move || cfg_arc.read().channel_external_peers("lark", &alias))
};
Ok(Arc::new(
LarkChannel::from_config(lk, alias, peer_resolver)
.with_workspace_dir(one_shot_channel_workspace_dir(View on GitHub (pinned to 88bb9c8533)
Solutions
- Rebuild with the feature enabled: cargo build --release -p zeroclaw-channels --features channel-qq (enable it on the binary crate you actually run, e.g. -p zeroclaw --features zeroclaw-channels/channel-qq)
- Or enable the bundle: cargo build --release --features channels-full (includes channel-qq)
- Or remove/disable the [channels.qq] block and any "qq" channel bindings from the config so the factory never selects the arm
- Before rebuilding, confirm the gap with zeroclaw_channels::listing::is_channel_type_compiled("qq") or the compiled-channel listing CLI
Example fix
# before cargo build --release # default features: qq arm compiled out # config.toml has [channels.qq] -> runtime bail # after cargo build --release --features channels-full # or --features channel-qq
Defensive patterns
Strategy: validation
Validate before calling
use zeroclaw_channels::listing::is_channel_type_compiled;
// before building channels, gate on compilation
if !is_channel_type_compiled("qq") {
eprintln!("this binary lacks the `channel-qq` feature; rebuild or drop [channels.qq]");
return;
} Type guard
fn qq_available() -> bool {
zeroclaw_channels::listing::is_channel_type_compiled("qq")
} Try / catch
match build_channel_by_id(&config_arc, "qq") {
Ok(ch) => { /* use channel */ }
Err(e) if e.to_string().contains("requires the `channel-qq` feature") => {
// build-time issue: skip channel, log rebuild hint, never retry
}
Err(e) => return Err(e),
} Prevention
- Run zeroclaw_channels::listing::configured_uncompiled_channels(&config.channels) at startup and fail fast with the full list instead of one error per channel
- Pin the feature list next to the config in deployment scripts so config and build cannot drift
- Prefer --features channels-full for a config-driven deployment that adds channels over time
When it happens
Trigger: Calling start_channels, build_channel_map, or build_channel_by_id with channel_id = "qq" (from an [agents.<alias>] channels binding or a [channels.qq] block) in a binary built without `--features channel-qq`. The QQ config parses fine; the bail happens when the factory tries to construct the channel actor.
Common situations: Building zeroclaw with the default feature set (default-channels compiles only acp-server, discord, email, filesystem, telegram, webhook), using a prebuilt/distro binary compiled with a channel subset, or enabling channels-full later and assuming QQ was already in it. QQ is in `channels-full` but not in `default-channels`.
Related errors
- Lark channel requires the `channel-lark` feature
- DingTalk channel requires the `channel-dingtalk` feature
- WeCom channel requires the `channel-wecom` feature
- WeCom WebSocket channel requires the `channel-wecom-ws` feat
- WeChat channel requires the `channel-wechat` feature
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/9e6a61a58d48a3cf.
Report an issue: GitHub.