{"record":{"id":"253ef45da9961ae7","repo":"zeroclaw-labs/zeroclaw","slug":"declarative-cron-job-id-agent-job-requires-a","errorCode":null,"errorMessage":"Declarative cron job '{id}': agent job requires a non-empty 'prompt'","messagePattern":"Declarative cron job '(.+?)': agent job requires a non-empty 'prompt'","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-runtime/src/cron/store.rs","lineNumber":1411,"sourceCode":"}\n\n/// Validate a declarative cron job definition.\nfn validate_decl(id: &str, decl: &zeroclaw_config::schema::CronJobDecl) -> Result<()> {\n    if id.trim().is_empty() {\n        anyhow::bail!(\"Declarative cron job has empty id\");\n    }\n\n    match decl.job_type.to_lowercase().as_str() {\n        \"shell\" => {\n            if decl.command.as_deref().is_none_or(|c| c.trim().is_empty()) {\n                anyhow::bail!(\n                    \"Declarative cron job '{id}': shell job requires a non-empty 'command'\"\n                );\n            }\n        }\n        \"agent\" => {\n            if decl.prompt.as_deref().is_none_or(|p| p.trim().is_empty()) {\n                anyhow::bail!(\n                    \"Declarative cron job '{id}': agent job requires a non-empty 'prompt'\"\n                );\n            }\n            if decl.shell_output_format != zeroclaw_config::schema::CronShellOutputFormat::default()\n            {\n                anyhow::bail!(\n                    \"Declarative cron job '{id}': shell_output_format is shell-only and cannot be set on an agent job\"\n                );\n            }\n        }\n        other => {\n            anyhow::bail!(\n                \"Declarative cron job '{id}': invalid job_type '{other}', expected 'shell' or 'agent'\"\n            );\n        }\n    }\n\n    Ok(())","sourceCodeStart":1393,"sourceCodeEnd":1429,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-runtime/src/cron/store.rs#L1393-L1429","documentation":"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.","triggerScenarios":"A [cron.<id>] table with job_type = \"agent\" and no prompt key, prompt = \"\", or prompt containing only whitespace.","commonSituations":"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).","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"],"exampleFix":"# before\n[cron.summarize]\njob_type = \"agent\"\nschedule = { kind = \"cron\", expression = \"0 9 * * *\" }\n\n# after\n[cron.summarize]\njob_type = \"agent\"\nschedule = { kind = \"cron\", expression = \"0 9 * * *\" }\nprompt = \"Summarize yesterday's commits and post a digest.\"","handlingStrategy":"validation","validationCode":"for (id, decl) in &decls {\n    if decl.job_type.eq_ignore_ascii_case(\"agent\")\n        && decl.prompt.as_deref().is_none_or(|p| p.trim().is_empty())\n    {\n        anyhow::bail!(\"cron job '{id}': agent job needs a non-empty 'prompt'\");\n    }\n}","typeGuard":"fn agent_decl_is_runnable(decl: &zeroclaw_config::schema::CronJobDecl) -> bool {\n    !decl.job_type.eq_ignore_ascii_case(\"agent\")\n        || decl.prompt.as_deref().is_some_and(|p| !p.trim().is_empty())\n}","tryCatchPattern":"if let Err(err) = zeroclaw_runtime::cron::sync_declarative_jobs(&config, &decls) {\n    if err.to_string().contains(\"agent job requires\") {\n        eprintln!(\"config error: an agent [cron.<id>] table is missing 'prompt'\");\n    }\n    return Err(err);\n}","preventionTips":["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"],"tags":["cron","config-validation","agent"],"backgroundTag":"config-validation-failed","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}