zeroclaw-labs/zeroclaw · error · anyhow::Error
Declarative cron job '{id}': shell_output_format is shell-on
Error message
Declarative cron job '{id}': shell_output_format is shell-only and cannot be set on an agent job What it means
shell_output_format (wrapped or raw) only controls how a shell job's stdout/stderr is formatted, so validate_decl rejects it on agent jobs. Setting it on job_type = "agent" is a config mistake that would otherwise be silently ignored; validation fails during sync_declarative_jobs before any DB write.
Source
Thrown at crates/zeroclaw-runtime/src/cron/store.rs:1417
}
match decl.job_type.to_lowercase().as_str() {
"shell" => {
if decl.command.as_deref().is_none_or(|c| c.trim().is_empty()) {
anyhow::bail!(
"Declarative cron job '{id}': shell job requires a non-empty 'command'"
);
}
}
"agent" => {
if decl.prompt.as_deref().is_none_or(|p| p.trim().is_empty()) {
anyhow::bail!(
"Declarative cron job '{id}': agent job requires a non-empty 'prompt'"
);
}
if decl.shell_output_format != zeroclaw_config::schema::CronShellOutputFormat::default()
{
anyhow::bail!(
"Declarative cron job '{id}': shell_output_format is shell-only and cannot be set on an agent job"
);
}
}
other => {
anyhow::bail!(
"Declarative cron job '{id}': invalid job_type '{other}', expected 'shell' or 'agent'"
);
}
}
Ok(())
}
/// Convert a `CronScheduleDecl` to the runtime `Schedule` type.
fn convert_schedule_decl(decl: &zeroclaw_config::schema::CronScheduleDecl) -> Result<Schedule> {
use zeroclaw_config::schema::CronScheduleDecl;
match decl {View on GitHub (pinned to 88bb9c8533)
Solutions
- Remove the shell_output_format line from the agent job
- Or set job_type = "shell" if the raw output format was intentional
Example fix
# before [cron.report] job_type = "agent" prompt = "Write the weekly report." shell_output_format = "raw" # after [cron.report] job_type = "agent" prompt = "Write the weekly report."
Defensive patterns
Strategy: validation
Validate before calling
use zeroclaw_config::schema::CronShellOutputFormat;
for (id, decl) in &decls {
if decl.job_type.eq_ignore_ascii_case("agent")
&& decl.shell_output_format != CronShellOutputFormat::default()
{
anyhow::bail!("cron job '{id}': shell_output_format is shell-only");
}
} Type guard
fn agent_decl_has_no_shell_format(decl: &zeroclaw_config::schema::CronJobDecl) -> bool {
!decl.job_type.eq_ignore_ascii_case("agent")
|| decl.shell_output_format == zeroclaw_config::schema::CronShellOutputFormat::default()
} Try / catch
if let Err(err) = zeroclaw_runtime::cron::sync_declarative_jobs(&config, &decls) {
if err.to_string().contains("shell_output_format") {
eprintln!("config error: remove shell_output_format from agent cron jobs");
}
return Err(err);
} Prevention
- Remember shell_output_format only affects shell jobs; never carry it over when switching job_type
- Diff config before/after converting a job between types and remove orphaned fields
When it happens
Trigger: A [cron.<id>] table with job_type = "agent" and shell_output_format = "raw" (any value other than the default "wrapped").
Common situations: Copying a shell job block and changing job_type to "agent" while leaving shell_output_format behind; experimenting with raw output on a job that was later converted to an agent job.
Understand the failure class
Background: Config validation failed: what "invalid value for {key}" and settings-rejection errors mean across 19 open-source libraries — this error's family across 19 libraries.
Related errors
- Declarative cron job '{id}': agent job requires a non-empty
- Declarative cron job has empty id
- Declarative cron job '{id}': shell job requires a non-empty
- Declarative cron job '{id}': invalid job_type '{other}', exp
- ACP request_permission failed: {} ({})
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/bdf089662c6cda8b.
Report an issue: GitHub.