Skip to content

v2026.6.5: Cron doctor preflight overwrites API-updated schedules with stale legacy JSON data #91944

Description

@suifatt7799-oss

Version: 2026.6.5

Summary:
After upgrading to 2026.6.5, a cron job that had its schedule updated via the cron.update API was triggered at the wrong time on gateway restart — based on the old schedule stored in a legacy JSON file, not the updated SQLite record.

Steps to reproduce:

  1. Have a cron job previously migrated from legacy JSON store to SQLite (.migrated file remains on disk as migration artifact)
  2. Update the job's schedule via the cron.update API (e.g., 18 15 10 * *18 15 11 * *)
  3. Confirm the update is reflected in SQLite (cron_jobs table shows new schedule, updated next_run_at_ms)
  4. Upgrade gateway to v2026.6.5 → gateway restarts, doctor preflight runs
  5. Doctor preflight reads the legacy jobs.json.migrated file which still contains the OLD schedule
  6. Migration overwrites (or re-evaluates based on) the old schedule in SQLite
  7. Cron engine on startup detects the job as "missed" (old schedule date has already passed) and fires it immediately after a 120s deferral

Log evidence from /tmp/openclaw/openclaw-YYYY-MM-DD.log:

cron: staggering missed jobs to prevent gateway overload  { totalMissed: 1 }
cron: deferring missed agent jobs until after gateway startup  { count: 1, delayMs: 120000 }

The legacy JSON file had the old schedule; the SQLite had the new one. The doctor migration picked the stale version.

Root cause:
The doctor preflight cron migration reads from legacy JSON stores without checking whether the corresponding SQLite record already has newer data (e.g., by comparing cron_jobs.updated_at against the JSON file's mtime, or checking if the SQLite record exists at all for a given job ID).

Suggested fix:

  • Before migrating a job from a legacy JSON store, check if the job ID already exists in the cron_jobs SQLite table
  • If it exists and cron_jobs.updated_at > source_file.mtime, skip the migration for that job
  • Or alternatively: treat .migrated files as truly done and never re-read them during doctor preflight

Impact:
For users who have updated cron schedules via the API after the initial JSON→SQLite migration, upgrading to 2026.6.5 can cause cron jobs to fire unexpectedly at the wrong time based on stale schedule data. This is particularly dangerous for scheduled outbound messaging jobs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High-priority user-facing bug, regression, or broken workflow.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions