Skip to content

fix(cron): migrate legacy schedule cron fields on load#28889

Merged
Takhoffman merged 1 commit intoopenclaw:mainfrom
Sid-Qin:fix/28861-cron-legacy-cron-field-migration
Mar 1, 2026
Merged

fix(cron): migrate legacy schedule cron fields on load#28889
Takhoffman merged 1 commit intoopenclaw:mainfrom
Sid-Qin:fix/28861-cron-legacy-cron-field-migration

Conversation

@Sid-Qin
Copy link
Contributor

@Sid-Qin Sid-Qin commented Feb 27, 2026

Summary

  • Problem: Legacy cron jobs created by older versions may still store schedule.cron and jobId, while current runtime expects schedule.expr and id, causing schedule evaluation errors and silent non-firing jobs.
  • Why it matters: Existing production cron jobs can stop running right after upgrade, with users seeing no expected deliveries.
  • What changed: Added load-time store migration in src/cron/service/store.ts for jobId -> id, schedule.cron -> schedule.expr, and canonical wakeMode; added defensive fallback for legacy cron field in src/cron/schedule.ts; normalized legacy schedule.cron in src/cron/normalize.ts; added regression tests.
  • What did NOT change: No new cron syntax, no scheduler cadence changes beyond legacy-field compatibility.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

User-visible / Behavior Changes

  • Legacy jobs that still use schedule.cron now migrate automatically and continue running.
  • Legacy jobs with jobId now normalize to id during load.
  • Missing/invalid wakeMode on legacy records defaults to now during migration.

Security Impact (required)

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No

Repro + Verification

Environment

  • OS: macOS 26.3 (dev), legacy repro from Ubuntu/docker issue report
  • Runtime: Node.js + pnpm workspace tests
  • Integration/channel: Cron service

Steps

  1. Prepare a legacy jobs.json entry with schedule: { kind: "cron", cron: "*/5 * * * *" } and jobId instead of id.
  2. Start cron service and list jobs.

Expected

  • Job is loaded with canonical fields (id, schedule.expr) and keeps scheduling.

Actual

  • Before fix: schedule evaluation could fail due to missing expr, and legacy fields were not normalized.
  • After fix: legacy fields are migrated on load and scheduling proceeds normally.

Evidence

  • Added regression tests:
    • src/cron/service.store-migration.test.ts
    • src/cron/schedule.test.ts
    • src/cron/normalize.test.ts
  • Test run:
    • pnpm --dir /Users/sidqin/Desktop/openclaw-contrib exec vitest src/cron/service.store-migration.test.ts src/cron/schedule.test.ts src/cron/normalize.test.ts
    • Result: 3 files passed, 41 tests passed.

Human Verification (required)

  • Verified scenarios:
    • Legacy store record with schedule.cron migrates to schedule.expr.
    • Legacy jobId migrates to canonical id.
    • Runtime schedule computation accepts legacy cron field defensively.
  • Edge cases checked:
    • Existing canonical expr remains preferred.
    • Missing wakeMode is normalized consistently.
  • What I did not verify:
    • Full end-to-end cron delivery against external chat providers in a live deployment.

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? No
  • Migration needed? No (automatic load-time migration)

Failure Recovery (if this breaks)

  • How to disable/revert: Revert this commit or redeploy previous build.
  • Files/config to restore: src/cron/service/store.ts, src/cron/schedule.ts, src/cron/normalize.ts.
  • Known bad symptoms: Legacy cron records may fail to fire again after rollback.

Risks and Mitigations

  • Risk: Mutating legacy store data on load can touch many records in one pass.
  • Mitigation: Migration is deterministic, narrow in scope, and covered by focused regression tests.

Backfill legacy jobs that still use schedule.cron and jobId so upgraded instances keep firing existing cron schedules instead of failing silently.

Closes openclaw#28861
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 27, 2026

Greptile Summary

This PR adds automatic migration for legacy cron job fields to prevent silent failures after upgrades:

  • Migrates jobIdid with trimming and cleanup
  • Migrates schedule.cronschedule.expr with fallback support
  • Normalizes wakeMode to canonical values ("now" or "next-heartbeat"), defaulting to "now"
  • Adds defensive fallback in schedule computation to read legacy cron field if expr is missing
  • Migration runs automatically at store load time and is deterministic

The implementation is thorough and defensive:

  • Prefers canonical fields over legacy fields when both exist
  • Always cleans up legacy fields after migration
  • Includes comprehensive test coverage across all three affected modules
  • Uses consistent patterns for trimming, type checking, and normalization

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The changes are well-scoped, defensive, and thoroughly tested. The migration logic handles edge cases properly (trimming, type checking, preferring canonical fields), and the three-layer approach (store migration, normalize, defensive fallback) ensures robustness. Test coverage validates both in-memory and persisted state after migration.
  • No files require special attention

Last reviewed commit: 87ccc36

@Takhoffman Takhoffman merged commit 504c1f3 into openclaw:main Mar 1, 2026
57 of 72 checks passed
hwb96 pushed a commit to hwb96/openclaw that referenced this pull request Mar 1, 2026
Backfill legacy jobs that still use schedule.cron and jobId so upgraded instances keep firing existing cron schedules instead of failing silently.

Closes openclaw#28861
zooqueen added a commit to hanzoai/bot that referenced this pull request Mar 1, 2026
Cherry-pick from upstream openclaw/openclaw 504c1f3.
Migrates legacy schedule.cron → schedule.expr, jobId → id, and
defaults wakeMode to "now" when missing from old store files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ansh pushed a commit to vibecode/openclaw that referenced this pull request Mar 2, 2026
Backfill legacy jobs that still use schedule.cron and jobId so upgraded instances keep firing existing cron schedules instead of failing silently.

Closes openclaw#28861
steipete pushed a commit to Sid-Qin/openclaw that referenced this pull request Mar 2, 2026
Backfill legacy jobs that still use schedule.cron and jobId so upgraded instances keep firing existing cron schedules instead of failing silently.

Closes openclaw#28861
safzanpirani pushed a commit to safzanpirani/clawdbot that referenced this pull request Mar 2, 2026
Backfill legacy jobs that still use schedule.cron and jobId so upgraded instances keep firing existing cron schedules instead of failing silently.

Closes openclaw#28861
steipete pushed a commit to Sid-Qin/openclaw that referenced this pull request Mar 2, 2026
Backfill legacy jobs that still use schedule.cron and jobId so upgraded instances keep firing existing cron schedules instead of failing silently.

Closes openclaw#28861
robertchang-ga pushed a commit to robertchang-ga/openclaw that referenced this pull request Mar 2, 2026
Backfill legacy jobs that still use schedule.cron and jobId so upgraded instances keep firing existing cron schedules instead of failing silently.

Closes openclaw#28861
hanqizheng pushed a commit to hanqizheng/openclaw that referenced this pull request Mar 2, 2026
Backfill legacy jobs that still use schedule.cron and jobId so upgraded instances keep firing existing cron schedules instead of failing silently.

Closes openclaw#28861
execute008 pushed a commit to execute008/openclaw that referenced this pull request Mar 2, 2026
Backfill legacy jobs that still use schedule.cron and jobId so upgraded instances keep firing existing cron schedules instead of failing silently.

Closes openclaw#28861
dorgonman pushed a commit to kanohorizonia/openclaw that referenced this pull request Mar 3, 2026
Backfill legacy jobs that still use schedule.cron and jobId so upgraded instances keep firing existing cron schedules instead of failing silently.

Closes openclaw#28861
sachinkundu pushed a commit to sachinkundu/openclaw that referenced this pull request Mar 6, 2026
Backfill legacy jobs that still use schedule.cron and jobId so upgraded instances keep firing existing cron schedules instead of failing silently.

Closes openclaw#28861
zooqueen added a commit to hanzoai/bot that referenced this pull request Mar 6, 2026
Cherry-pick from upstream openclaw/openclaw 504c1f3.
Migrates legacy schedule.cron → schedule.expr, jobId → id, and
defaults wakeMode to "now" when missing from old store files.
zooqueen pushed a commit to hanzoai/bot that referenced this pull request Mar 6, 2026
Backfill legacy jobs that still use schedule.cron and jobId so upgraded instances keep firing existing cron schedules instead of failing silently.

Closes openclaw#28861
Mateljan1 pushed a commit to Mateljan1/openclaw that referenced this pull request Mar 7, 2026
Backfill legacy jobs that still use schedule.cron and jobId so upgraded instances keep firing existing cron schedules instead of failing silently.

Closes openclaw#28861
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Ineffective monitoring for failing cron jobs

2 participants