zeroclaw-labs/zeroclaw · error
wecom_ws channel is not connected
Error message
wecom_ws channel is not connected
What it means
The wecom_ws arm of deliver_announcement has no stateless send path: it first confirms [channels.wecom_ws.<alias>] exists (else the separate "not configured" error) and then always bails with "wecom_ws channel is not connected". WeCom WebSocket delivery only works through a live connected instance, normally looked up earlier in CRON_CHANNEL_REGISTRY; reaching this bail means the alias is configured but no live connection was registered at delivery time.
Source
Thrown at crates/zeroclaw-channels/src/orchestrator/mod.rs:13004
wh.auth_header.clone(),
wh.secret.clone(),
wh.max_retries,
wh.retry_base_delay_ms,
wh.retry_max_delay_ms,
);
zeroclaw_api::channel::Channel::send(&ch, &make_msg(&safe_output)).await?;
}
#[cfg(not(feature = "channel-webhook"))]
"webhook" => {
anyhow::bail!("Webhook channel requires the `channel-webhook` feature");
}
"wecom_ws" | "wecom-ws" => {
let _ = config
.channels
.wecom_ws
.get(alias)
.ok_or_else(not_configured)?;
anyhow::bail!("wecom_ws channel is not connected");
}
#[cfg(feature = "channel-email")]
"email" => {
let em = config
.channels
.email
.get(alias)
.ok_or_else(not_configured)?;
let peers = config.channel_external_peers("email", alias);
let peer_resolver: Arc<dyn Fn() -> Vec<String> + Send + Sync> =
Arc::new(move || peers.clone());
let ch = EmailChannel::new(em.clone(), alias.to_string(), peer_resolver);
zeroclaw_api::channel::Channel::send(&ch, &make_msg(&safe_output)).await?;
}
#[cfg(not(feature = "channel-email"))]
"email" => {
anyhow::bail!("Email channel requires the `channel-email` feature");
}View on GitHub (pinned to 88bb9c8533)
Solutions
- Enable and start the wecom_ws channel so the orchestrator connects it at startup and registers it in CRON_CHANNEL_REGISTRY (registry hits return before this arm is reached)
- Check channel connection logs/state at delivery time and requeue the delivery until connected
- If you only need push delivery without a live socket, route the cron through the webhook channel instead
Example fix
# before [channels.wecom_ws.bot] corp_id = "..." # configured, but channel disabled / not connected [cron.alert] channel = "wecom_ws.bot" # -> bail: not connected # after [channels] enable = ["wecom_ws"] # channel starts, registers, cron delivers via live instance
Defensive patterns
Strategy: validation
Validate before calling
// Before a wecom_ws delivery, confirm the channel is actually up:
// (outside the crate, approximate with your own connection tracker)
if channel.starts_with("wecom_ws.") && !wecom_connected(alias) {
// defer the delivery instead of attempting it
return schedule_retry_in(Duration::from_secs(60)).await;
}
// inside zeroclaw-channels, the canonical check is the registry:
// CRON_CHANNEL_REGISTRY.read().unwrap_or_else(|e| e.into_inner()).contains_key(&channel.to_ascii_lowercase()) Try / catch
match deliver_announcement(&cfg, "wecom_ws.bot", &target, thread, &out).await {
Err(e) if e.to_string().ends_with("wecom_ws channel is not connected") => {
// Transient availability problem: requeue/defer this run; alert if it persists.
}
rest => rest?,
} Prevention
- Start wecom_ws channels at daemon startup so the registry path handles delivery before the static arm
- Monitor channel connection state and requeue wecom_ws crons while disconnected
- Prefer the webhook channel for push-style crons when no live WeCom socket is guaranteed
When it happens
Trigger: Calling deliver_announcement with channel = "wecom_ws.<alias>" (or "wecom-ws.<alias>") while the WeCom WebSocket channel is disabled, not yet started, or has dropped its connection; delivery before startup finished connecting.
Common situations: Cron firing during startup before the wecom_ws channel registered; the channel crashed or was disabled in config while its cron entries remained; using wecom_ws crons on a deployment that never runs the WeCom listener.
Related errors
- WeCom WebSocket channel requires the `channel-wecom-ws` feat
- WeCom WebSocket not connected
- WeCom channel requires the `channel-wecom` feature
- [channels.lark.{alias}] has use_feishu=false but cron channe
- Webhook channel requires the `channel-webhook` feature
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/ec3df09b2594d60e.
Report an issue: GitHub.