zeroclaw-labs/zeroclaw · error · anyhow::Error

Cron job '{job_id}': delivery is owned by [cron.{job_id}].de

Error message

Cron job '{job_id}': delivery is owned by [cron.{job_id}].delivery in config.toml for a declarative job, not the database. Edit the config and restart the daemon.

What it means

Error "Cron job '{job_id}': delivery is owned by [cron.{job_id}].delivery in config.toml for a declarative job, not the database. Edit the config and restart the daemon." thrown in zeroclaw-labs/zeroclaw.

Source

Thrown at crates/zeroclaw-runtime/src/cron/store.rs:504

    if let Some(name) = patch.name {
        job.name = Some(name);
    }
    if let Some(enabled) = patch.enabled {
        job.enabled = enabled;
    }
    if let Some(delivery) = patch.delivery {
        // A declarative job's delivery is owned by `[cron.<id>].delivery` in
        // config.toml. Writing it here would appear to succeed and then be
        // silently reverted by `sync_declarative_jobs` on the next daemon
        // start, which rewrites every declarative column from the config.
        // Reject at this boundary rather than persist a value the next sync
        // discards, matching how `shell_output_format` is handled below.
        //
        // Ownership is checked before shape: a declarative job rejects any
        // delivery patch, so reporting a missing recipient first would imply
        // that correcting it would let the write through.
        if job.source == "declarative" {
            anyhow::bail!(
                "Cron job '{job_id}': delivery is owned by [cron.{job_id}].delivery in \
                 config.toml for a declarative job, not the database. Edit the config \
                 and restart the daemon."
            );
        }
        // Match add_*_job: announce delivery must include channel + to.
        validate_delivery_config(Some(&delivery))?;
        job.delivery = delivery;
    }
    if let Some(model) = patch.model {
        job.model = Some(model);
    }
    if let Some(target) = patch.session_target {
        job.session_target = target;
    }
    if let Some(delete_after_run) = patch.delete_after_run {
        job.delete_after_run = delete_after_run;
    }

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Edit [cron.<job_id>].delivery in config.toml and restart the daemon instead of changing delivery via the database.

When it happens

Trigger: Thrown at crates/zeroclaw-runtime/src/cron/store.rs:504 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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