zeroclaw-labs/zeroclaw · error · anyhow::Error

Missing [channels.{channel_type}.{alias}] section in config.

Error message

Missing [channels.{channel_type}.{alias}] section in config.toml — configure the channel before pairing

What it means

merge_external_peer refuses to persist a paired identity for a channel instance that does not exist in canonical config: it walks cfg.channels_by_alias() (every [channels.<type>.<alias>] block) and requires an entry matching both channel_type and alias. The writer will not create authorization state for a channel the runtime reader would never load, so pairing fails fast with a pointer to the missing TOML section.

Source

Thrown at crates/zeroclaw-channels/src/identity_persist.rs:70

) -> anyhow::Result<bool> {
    use zeroclaw_config::multi_agent::{PeerGroupConfig, PeerUsername};
    use zeroclaw_config::providers::ChannelRef;

    let normalized = identity.trim();
    if normalized.is_empty() {
        anyhow::bail!("Cannot persist empty {channel_type} identity");
    }
    // Existence comes from the canonical channel registry
    // (`Config::channels_by_alias()` walks every configured
    // `[channels.<type>.<alias>]` block regardless of type), so this writer
    // holds no channel-type list of its own and a future QR-pairing channel
    // needs no edit here.
    let configured = cfg
        .channels_by_alias()
        .iter()
        .any(|info| info.channel_type == channel_type && info.alias == alias);
    if !configured {
        anyhow::bail!(
            "Missing [channels.{channel_type}.{alias}] section in config.toml — \
             configure the channel before pairing"
        );
    }

    // Already authorized through any group the reader matches (including
    // type-wide groups)? Then there is nothing to persist. This reuses the
    // reader itself, so writer and reader cannot disagree about what
    // "already authorized" means.
    if cfg
        .channel_external_peers(channel_type, alias)
        .iter()
        .any(|peer| peer == normalized)
    {
        return Ok(false);
    }

    let dotted_ref = format!("{channel_type}.{alias}");

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Add the missing [channels.<channel_type>.<alias>] section to config.toml with its required fields and enabled = true, then re-run the pairing
  2. Check the alias spelling — the error text names the exact channel_type/alias pair persistence looked for; it must match the TOML key character-for-character
  3. If the section exists but the error persists, confirm the running process actually reloaded config.toml (restart the runtime)

Example fix

# before (config.toml) — no wechat section
[peer_groups.default]
agents = ["main"]

# after
[channels.wechat.main]
enabled = true
# ...required wechat fields...

[peer_groups.default]
agents = ["main"]
Defensive patterns

Strategy: validation

Validate before calling

// Before starting a pairing flow, confirm the channel exists canonically:
let configured = cfg.channels_by_alias()
    .iter()
    .any(|info| info.channel_type == channel_type && info.alias == alias);
anyhow::ensure!(configured, "configure [channels.{channel_type}.{alias}] before pairing");

Try / catch

match persist_external_peer(persist.as_deref(), channel_type, alias, identity).await {
    Err(e) if e.to_string().contains("Missing [channels") => {
        // stop the pairing wizard and prompt the operator to add the TOML section
    }
    other => other?,
}

Prevention

When it happens

Trigger: A QR pairing completes for alias 'main' of type 'wechat' (or 'whatsapp') but config.toml has no [channels.wechat.main] block — e.g. the handle was constructed programmatically with an alias that differs from the configured one ('default' vs 'main'), or the channel section was deleted after the process started.

Common situations: Alias typo between the channel handle and the TOML block; a pairing test that builds a Config without the channel section; operator removed the channel block while a pairing flow was still in flight.

Related errors


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