zeroclaw-labs/zeroclaw · error · anyhow::Error
delivery.channel is required for announce mode
Error message
delivery.channel is required for announce mode
What it means
After the mode whitelist passes, announce mode must name a channel: delivery.channel must be present and non-empty after trimming. Missing, empty, or whitespace-only channel bails before target validation. A delivery.to target alone is not sufficient — the channel is required for announce.
Source
Thrown at crates/zeroclaw-runtime/src/cron/mod.rs:150
shell_output_format,
)
}
pub fn validate_delivery_config(delivery: Option<&DeliveryConfig>) -> Result<()> {
let Some(delivery) = delivery else {
return Ok(());
};
if delivery.mode.eq_ignore_ascii_case("none") {
return Ok(());
}
if !delivery.mode.eq_ignore_ascii_case("announce") {
bail!("unsupported delivery mode: {}", delivery.mode);
}
let channel = delivery.channel.as_deref().map(str::trim);
if channel.filter(|value| !value.is_empty()).is_none() {
bail!("delivery.channel is required for announce mode");
}
let has_target = delivery
.to
.as_deref()
.map(str::trim)
.is_some_and(|value| !value.is_empty());
if !has_target {
bail!("delivery.to is required for announce mode");
}
Ok(())
}
pub fn add_shell_job_with_approval(
config: &Config,
agent_alias: &str,
name: Option<String>,View on GitHub (pinned to 88bb9c8533)
Solutions
- Set delivery.channel to a configured, non-empty channel identifier
- Trim channel values if config sources may carry whitespace
- If no announcement is wanted, use mode 'none' instead of announce-without-channel
- Validate the whole delivery block in config loading, not just at job creation
Example fix
// before
delivery = { mode: "announce", channel: None, to: Some("@ops") }
// after
delivery = { mode: "announce", channel: Some("telegram:ops".into()), to: Some("@ops") } Defensive patterns
Strategy: validation
Validate before calling
if !delivery_is_valid(&delivery) {
anyhow::bail!("announce mode requires a non-empty delivery.channel");
}
cron.add_agent_job(spec, delivery).await?; Type guard
fn delivery_is_valid(d: &DeliveryConfig) -> bool {
if d.mode.eq_ignore_ascii_case("none") { return true; }
if !d.mode.eq_ignore_ascii_case("announce") { return false; }
d.channel.as_deref().map(|c| !c.trim().is_empty()).unwrap_or(false)
} Prevention
- Templates for announce-mode jobs must include the channel field
- Use mode 'none' when no announcement is wanted rather than leaving channel blank
- Validate the full delivery block in one place before job creation
- Trim channel values from user-edited configs
When it happens
Trigger: delivery = { mode: 'announce' } with channel omitted, set to "", or set to spaces; programmatically built configs that populate only the `to` field.
Common situations: Hand-written cron YAML/TOML forgetting the channel field; templates assuming a default channel; field renames during refactors leaving channel unset.
Related errors
- unsupported delivery mode: {}
- at least one topic must be configured
- at least one path must be configured
- at least one routing key must be configured
- cloud_ops.default_cloud must not be empty when cloud_ops is
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/63fdcc4b96f31511.
Report an issue: GitHub.