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

{channel_type} identity cannot be empty

Error message

{channel_type} identity cannot be empty

What it means

Thrown by bind_channel_identity_into after normalizing the incoming identity: the channel-specific normalizer (trim for wechat/line, telegram numeric-id normalization) produced an empty string. A peer group entry keyed on an empty identity would match nothing (or worse, over-match), so the bind is refused.

Source

Thrown at crates/zeroclaw-channels/src/orchestrator/mod.rs:8666

pub fn bind_channel_identity_into(
    config: &mut Config,
    channel_type: &str,
    alias: &str,
    identity: &str,
) -> Result<bool> {
    use zeroclaw_config::multi_agent::{PeerGroupConfig, PeerUsername};
    use zeroclaw_config::providers::ChannelRef;

    let Some(normalize) = channel_identity_normalizer(channel_type) else {
        anyhow::bail!(
            "Channel type `{channel_type}` does not support identity binding \
             (supported: telegram, wechat, line)."
        );
    };

    let normalized = normalize(identity);
    if normalized.is_empty() {
        anyhow::bail!("{channel_type} identity cannot be empty");
    }

    // The alias must name an existing `[channels.<type>.<alias>]` section.
    // Binding into a phantom alias would mint a peer group the runtime never
    // reads (it resolves authorization per the alias the channel actually
    // runs under), so fail loudly instead of silently authorizing nobody.
    if !channel_alias_configured(config, channel_type, alias) {
        anyhow::bail!(
            "{channel_type} channel alias `{alias}` is not configured. Run \
             `zeroclaw config set channels.{channel_type}.{alias}.bot_token <token>` \
             (see docs/book/src/channels/overview.md for the full field list)."
        );
    }

    let group_name = format!("{channel_type}_{alias}");
    let channel_ref = format!("{channel_type}.{alias}");
    let group = config
        .peer_groups

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Supply the real chat identity: for telegram the numeric user/chat ID, for wechat/line the non-empty username/id string
  2. If scripting, verify the variable is set and non-empty before invoking bind
  3. Trim obvious whitespace/quotes that may have been introduced by copy-paste

Example fix

# before
zeroclaw bind telegram default "$TG_ID"   # TG_ID unset -> ""
# error: telegram identity cannot be empty

# after
export TG_ID=123456789
zeroclaw bind telegram default "$TG_ID"
Defensive patterns

Strategy: validation

Validate before calling

let identity = identity.trim();
if identity.is_empty() {
    return Ok(notify("identity is required for binding"));
}
bind_channel_identity_into(&mut config, channel_type, alias, identity)?;

Try / catch

Err(err) if err.to_string().contains("identity cannot be empty") => {
    // re-prompt for the numeric telegram id / wechat-line username
}

Prevention

When it happens

Trigger: Calling bind_channel_identity_into with identity = "", a whitespace-only string, or a value the normalizer reduces to nothing (e.g. a telegram identity consisting solely of characters stripped by normalize_telegram_identity).

Common situations: CLI bind command invoked without the identity argument; gateway bind endpoint receives an empty payload field; shell script passes an unset variable (`$TG_ID` when it was never exported).

Related errors


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