From 1f0bb8742fd3502c9d7b39c2e75faf1d07406971 Mon Sep 17 00:00:00 2001 From: teknium1 Date: Tue, 17 Mar 2026 04:03:42 -0700 Subject: [PATCH] fix(cron): get_due_jobs read jobs.json twice creating race window get_due_jobs() called load_jobs() twice: once for filtering (with _apply_skill_fields) and once for saving updates. Between the two reads, another process could modify jobs.json, causing the filtering and saving to operate on different versions. Fix: load once, deepcopy for the skill-applied working list. --- cron/jobs.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cron/jobs.py b/cron/jobs.py index b749c51f..a647a18b 100644 --- a/cron/jobs.py +++ b/cron/jobs.py @@ -5,6 +5,7 @@ Jobs are stored in ~/.hermes/cron/jobs.json Output is saved to ~/.hermes/cron/output/{job_id}/{timestamp}.md """ +import copy import json import logging import tempfile @@ -539,8 +540,8 @@ def get_due_jobs() -> List[Dict[str, Any]]: immediately. This prevents a burst of missed jobs on gateway restart. """ now = _hermes_now() - jobs = [_apply_skill_fields(j) for j in load_jobs()] - raw_jobs = load_jobs() # For saving updates + raw_jobs = load_jobs() + jobs = [_apply_skill_fields(j) for j in copy.deepcopy(raw_jobs)] due = [] needs_save = False