zeroclaw-labs/zeroclaw · warning · anyhow::Error
Cron job '{}' not found
Error message
Cron job '{}' not found What it means
apply_run_completion_state runs the post-run UPDATE (last-run timestamp, bounded output) after persist_run_result / persist_run_completion_state record a finished run. SQLite reports 0 rows changed when the cron_jobs row for job.id no longer exists, so the store bails: the job vanished between dispatch and completion, typically deleted by a concurrent connection (CLI delete, gateway API, or sync_declarative_jobs removing a job no longer in config).
Source
Thrown at crates/zeroclaw-runtime/src/cron/store.rs:1599
match action {
RunCompletionAction::Reschedule => {
let next_run = next_run_for_schedule(&job.schedule, job_state_at)?;
let changed = conn
.execute(
"UPDATE cron_jobs
SET next_run = ?1, last_run = ?2, last_status = ?3, last_output = ?4
WHERE id = ?5",
params![
next_run.to_rfc3339(),
job_state_at.to_rfc3339(),
status,
bounded_output.as_deref(),
job.id,
],
)
.context("Failed to update cron job run state")?;
if changed == 0 {
anyhow::bail!("Cron job '{}' not found", job.id);
}
}
RunCompletionAction::Disable => {
let changed = conn
.execute(
"UPDATE cron_jobs
SET enabled = 0, last_run = ?1, last_status = ?2, last_output = ?3
WHERE id = ?4",
params![
job_state_at.to_rfc3339(),
status,
bounded_output.as_deref(),
job.id,
],
)
.context("Failed to disable completed one-shot cron job")?;
if changed == 0 {
anyhow::bail!("Cron job '{}' not found", job.id);View on GitHub (pinned to 88bb9c8533)
Solutions
- Check the cron job list (or cron_jobs table): if you deleted the job yourself, the error is benign — the run finished, only its state write had no target row
- If the job should still exist, verify it is still declared in zeroclaw.toml (declarative jobs missing from config are deleted on sync) and restart the daemon
- Ensure only one scheduler/daemon runs against the workspace database
Example fix
// before — completion state write aborts the caller
persist_run_result(&config, &job, &result)?;
// after — tolerate a job deleted mid-run
if let Err(err) = persist_run_result(&config, &job, &result) {
let msg = err.to_string();
if msg.starts_with("Cron job") && msg.ends_with("not found") {
tracing::warn!(job = %job.id, "job deleted while run was in flight; dropping completion state");
} else {
return Err(err);
}
} Defensive patterns
Strategy: try-catch
Validate before calling
// immediately before recording completion state, confirm the row survived
let present: i64 = conn
.query_row(
"SELECT COUNT(*) FROM cron_jobs WHERE id = ?1",
rusqlite::params![job.id],
|r| r.get(0),
)
.unwrap_or(0);
if present == 0 {
// job was deleted mid-run; skip completion bookkeeping instead of erroring
} Try / catch
if let Err(err) = persist_run_result(&config, &job, &result) {
let msg = err.to_string();
if msg.starts_with("Cron job") && msg.ends_with("not found") {
tracing::warn!(job = %job.id, "job deleted while run was in flight; dropping completion state");
return Ok(());
}
return Err(err);
} Prevention
- Run only one daemon/scheduler against a workspace database
- When removing declarative jobs from zeroclaw.toml, expect in-flight runs to log this on completion and treat it as expected
- Disable a job before deleting it if you need in-flight runs to drain cleanly
When it happens
Trigger: A run is in flight while the job row is deleted: running a job removal command from another shell, restarting the daemon after deleting the job from zeroclaw.toml (sync deletes stale declarative jobs), or two scheduler processes sharing one workspace database.
Common situations: Cancelling a long-running one-shot job mid-execution; editing zeroclaw.toml and restarting while an overdue declarative job executes; accidentally running duplicate daemons against the same data dir.
Related errors
- purge_agent not supported by this memory backend
- rename_agent not supported by this memory backend
- Messages database not found at {}. Ensure Messages.app is se
- knowledge graph node limit reached ({}/{})
- {flag} = true requires memory.backend = "sqlite" (typed memo
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/69e1b69724a948e0.
Report an issue: GitHub.