zeroclaw-labs/zeroclaw · error · anyhow::Error
Declarative cron job '{id}': agent job requires a non-empty
Error message
Declarative cron job '{id}': agent job requires a non-empty 'prompt' What it means
validate_decl enforces that declarative cron jobs with job_type = "agent" carry a non-empty prompt. The prompt is the instruction sent to the LLM when the job fires, so an agent job without one has nothing to run; validation fails during sync_declarative_jobs before any DB write.
Source
Thrown at crates/zeroclaw-runtime/src/cron/store.rs:1411
}
/// Validate a declarative cron job definition.
fn validate_decl(id: &str, decl: &zeroclaw_config::schema::CronJobDecl) -> Result<()> {
if id.trim().is_empty() {
anyhow::bail!("Declarative cron job has empty id");
}
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(())View on GitHub (pinned to 88bb9c8533)
Solutions
- Add prompt = "<instruction for the agent>" to the [cron.<id>] table
- If the job should run a command instead, set job_type = "shell" and provide a non-empty command
- Make sure prompt is not only whitespace
Example fix
# before
[cron.summarize]
job_type = "agent"
schedule = { kind = "cron", expression = "0 9 * * *" }
# after
[cron.summarize]
job_type = "agent"
schedule = { kind = "cron", expression = "0 9 * * *" }
prompt = "Summarize yesterday's commits and post a digest." Defensive patterns
Strategy: validation
Validate before calling
for (id, decl) in &decls {
if decl.job_type.eq_ignore_ascii_case("agent")
&& decl.prompt.as_deref().is_none_or(|p| p.trim().is_empty())
{
anyhow::bail!("cron job '{id}': agent job needs a non-empty 'prompt'");
}
} Type guard
fn agent_decl_is_runnable(decl: &zeroclaw_config::schema::CronJobDecl) -> bool {
!decl.job_type.eq_ignore_ascii_case("agent")
|| decl.prompt.as_deref().is_some_and(|p| !p.trim().is_empty())
} Try / catch
if let Err(err) = zeroclaw_runtime::cron::sync_declarative_jobs(&config, &decls) {
if err.to_string().contains("agent job requires") {
eprintln!("config error: an agent [cron.<id>] table is missing 'prompt'");
}
return Err(err);
} Prevention
- Treat prompt as the agent-job equivalent of command and always set one of the two
- Do not rely on heartbeat.message-style fallbacks for cron agent jobs — none applies
- Validate the decl map in a unit test whenever config is generated programmatically
When it happens
Trigger: A [cron.<id>] table with job_type = "agent" and no prompt key, prompt = "", or prompt containing only whitespace.
Common situations: Converting a shell job to an agent job and replacing command with prompt only partially; filling in model and allowed_tools but forgetting the prompt; expecting the heartbeat fallback message to apply to cron agent jobs (it does not).
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}': shell_output_format is shell-on
- 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/253ef45da9961ae7.
Report an issue: GitHub.