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

  1. 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
  2. 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
  3. 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

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


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/69e1b69724a948e0. Report an issue: GitHub.