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

  1. 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)
  2. Or enable the bundle: cargo build --release --features channels-full (includes channel-qq)
  3. Or remove/disable the [channels.qq] block and any "qq" channel bindings from the config so the factory never selects the arm
  4. 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

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


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/9e6a61a58d48a3cf. Report an issue: GitHub.