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

channel '{}' does not support forge API requests

Error message

channel '{}' does not support forge API requests

What it means

The `channels remove` subcommand (ChannelCommands::Remove arm in handle_command, src/channels/mod.rs:82) is intentionally not implemented and unconditionally bails, pointing at the config file. Channel entries are plain TOML tables under `channels`, so removal is a file edit, not a command. Nothing is modified; the command exits non-zero.

Source

Thrown at crates/zeroclaw-api/src/channel.rs:767

        None
    }

    /// Whether the orchestrator should drop an inbound message as
    /// self-authored (multi-agent self-loop guard). Default compares
    /// `msg.sender` against [`Self::self_handle`] case-insensitively after
    /// stripping a leading `@` from each side. Override only for platforms
    /// whose identity comparison is non-string.
    fn drop_self_messages(&self, msg: &ChannelMessage) -> bool {
        let Some(handle) = self.self_handle() else {
            return false;
        };
        let handle_norm = handle.trim_start_matches('@').to_ascii_lowercase();
        let sender_norm = msg.sender.trim_start_matches('@').to_ascii_lowercase();
        !handle_norm.is_empty() && handle_norm == sender_norm
    }

    async fn forge_request(&self, _request: ForgeApiRequest) -> anyhow::Result<ForgeApiResponse> {
        anyhow::bail!(
            "channel '{}' does not support forge API requests",
            self.name()
        )
    }

    /// Whether an inbound message is a direct one-to-one conversation with
    /// the bot. A DM is definitionally addressed to the bot, so the
    /// orchestrator skips the reply-intent classifier and goes straight to
    /// the tool-capable agent turn. Default `false`: channels that cannot
    /// prove a one-to-one context keep the classifier precheck.
    fn is_direct_message(&self, _msg: &ChannelMessage) -> bool {
        false
    }

    /// Whether this channel supports multi-message streaming delivery.
    fn supports_multi_message_streaming(&self) -> bool {
        false
    }

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Edit ~/.zeroclaw/config.toml and delete the `[channels.<type>.<alias>]` table for that channel
  2. Restart the gateway / re-run `zeroclaw channels list` so the removal is reflected
  3. If the channel was the source of errors, run `zeroclaw channels doctor` afterwards to confirm a clean config

Example fix

# before
$ zeroclaw channels remove telegram-main
Error: Remove channel 'telegram-main' — edit ~/.zeroclaw/config.toml directly

# after
$ # delete the [channels.telegram.telegram-main] table in ~/.zeroclaw/config.toml
$ zeroclaw channels list
Defensive patterns

Strategy: validation

Validate before calling

// Reject unimplemented subcommands before dispatching to handle_command.
fn is_implemented(cmd: &zeroclaw::ChannelCommands) -> bool {
    !matches!(cmd, zeroclaw::ChannelCommands::Remove { .. })
}

Try / catch

if let Err(e) = channels::handle_command(cmd, &config).await {
    if e.to_string().contains("edit ~/.zeroclaw/config.toml directly") {
        // Deterministic unsupported-command bail: perform removal as a
        // TOML edit of the [channels.<type>.<alias>] table instead.
    }
}

Prevention

When it happens

Trigger: Invoking `zeroclaw channels remove <name>` from the CLI, or dispatching a ChannelCommands::Remove value into channels::handle_command programmatically. Every invocation of this arm bails.

Common situations: Cleaning up a misconfigured channel; scripts or docs that assume a symmetric add/remove CLI exists.

Related errors


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