Skip to content

Skip cron jobs with invalid schedules instead of 500-ing every cron mutation#243

Merged
ramonski merged 2 commits into
masterfrom
fix/cron-invalid-schedule-500
Jul 9, 2026
Merged

Skip cron jobs with invalid schedules instead of 500-ing every cron mutation#243
ramonski merged 2 commits into
masterfrom
fix/cron-invalid-schedule-500

Conversation

@ramonski

@ramonski ramonski commented Jul 9, 2026

Copy link
Copy Markdown
Member

Context

The cron editor's pencil kept reverting a job's timeout to its template default (900), and edits appeared not to save. Root cause is a backend 500, not the UI.

hn-ai-daily had an out-of-range schedule 06 45 * * * (hour 45; max is 23). sync_jobs re-adds every enabled job on every cron mutation, and _add_job_to_scheduler (kaisho/cron/scheduler.py) only guarded the field-count check (_cron_kwargs), not CronTrigger's value validation. So that one malformed job made every cron enable/disable/update throw a ValueError → 500.

The mutation writes the file before sync_jobs, so the value did persist to disk — but the request 500'd, the frontend's React Query mutation errored, no refetch happened, and the edit dialog kept showing the stale cached value. That is the "timeout reverts to 900" symptom.

Why this matters

One bad job silently bricks all cron mutations, including the save that would fix the bad job — a deadlock the user can only escape by hand-editing jobs.yaml.

Fix

Validate the CronTrigger inside the guard in _add_job_to_scheduler, so a malformed schedule (wrong field count or out-of-range value) is logged and skipped instead of aborting the whole sync. The remaining jobs schedule normally and mutations return 200.

Adds tests/test_cron_scheduler.py covering: valid job registers, out-of-range hour is skipped without raising, wrong field count is skipped, and a bad job in a set does not block the good ones.

Out of scope

  • Save-time schedule validation (a 400 with a clear message on POST/PATCH) so invalid schedules can't be stored in the first place — worth a follow-up.
  • Surfacing skipped/invalid jobs in the UI (today they're only logged).

…utation

A single job with an out-of-range schedule field (e.g. hour 45)
made every cron enable/disable/update return 500: sync_jobs
re-adds all enabled jobs on each mutation, and
_add_job_to_scheduler only guarded the field-count check, not
CronTrigger's value validation. The propagated ValueError also
broke the mutation's own file-write follow-through, so the
frontend never refetched and the edit dialog kept showing the
stale cached value (the timeout "reverts to 900" symptom).

Validate the trigger inside the guard so a malformed schedule is
logged and skipped, letting the rest of the sync proceed.
@ramonski ramonski self-assigned this Jul 9, 2026
@ramonski ramonski added the Bug 🐞 Something is broken label Jul 9, 2026
@ramonski ramonski merged commit f90abce into master Jul 9, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug 🐞 Something is broken

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant