Skip to content

fix(cron): recover null next_run_at jobs#19576

Merged
teknium1 merged 2 commits into
mainfrom
hermes/hermes-8c54fd4a
May 4, 2026
Merged

fix(cron): recover null next_run_at jobs#19576
teknium1 merged 2 commits into
mainfrom
hermes/hermes-8c54fd4a

Conversation

@teknium1

@teknium1 teknium1 commented May 4, 2026

Copy link
Copy Markdown
Contributor

Salvage of #19066 by @EthanGuo-coder onto current main.

Summary

get_due_jobs() silently skipped any cron/interval job whose next_run_at was null (happens when users hand-edit jobs.json, on partial migrations, or after a crash mid-write). Those jobs would never run again. Recompute next_run_at via compute_next_run() for cron/interval schedules with a missing timestamp, persist the recovered value, continue evaluation in the same tick.

Note: the PR's bug #2 (non-dict origin crash) was independently fixed on main already (#18722) — the parametrized test coverage is preserved, and _deliver_result now routes through _resolve_origin for consistent tolerance.

Changes

  • cron/jobs.py: recovery branch for cron/interval null next_run_at (+17/-3)
  • cron/scheduler.py: _deliver_result uses _resolve_origin helper
  • tests: new regressions for cron + interval recovery
  • scripts/release.py: AUTHOR_MAP entry for @EthanGuo-coder

Validation

scripts/run_tests.sh tests/cron/ → 296 passed

Original PR: #19066
Fixes: #18722

ethan and others added 2 commits May 4, 2026 01:32
Fixes #18722

get_due_jobs() now recomputes next_run_at via compute_next_run() for
cron/interval jobs that arrived with null next_run_at (e.g. via direct
jobs.json edits) instead of silently skipping them. _resolve_origin()
guards with isinstance(origin, dict), and _deliver_result() now routes
through _resolve_origin() so string/non-dict origins no longer crash
the ticker.

References: references #18735 (open competing fix from automated bulk PR touching 79 files); this PR is a focused single-issue contribution and adds the missing interval-recovery test variant

Co-Authored-By: Claude <noreply@anthropic.com>
…ance

Adds four regression tests guarding the bugfix in the previous commit:
- TestGetDueJobs::test_broken_cron_without_next_run_is_recovered exercises
  cron schedules whose next_run_at was lost; expects compute_next_run to
  repopulate it within get_due_jobs() rather than silently skipping the job.
- TestGetDueJobs::test_broken_interval_without_next_run_is_recovered does
  the same for interval schedules.
- TestResolveOrigin::test_string_origin_is_tolerated and
  test_non_dict_origin_is_tolerated confirm _resolve_origin() returns None
  for legacy/hand-edited origins (string, list, int) instead of raising.

Co-Authored-By: Claude <noreply@anthropic.com>
@teknium1 teknium1 merged commit 645b99a into main May 4, 2026
9 of 10 checks passed
@teknium1 teknium1 deleted the hermes/hermes-8c54fd4a branch May 4, 2026 08:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

cron: jobs with null next_run_at silently skipped; non-dict origin crashes ticker

1 participant