From d313a3b7d7524b7f7d702540b0c2d621e6945850 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Sat, 28 Mar 2026 08:15:31 -0700 Subject: [PATCH] fix: auto-repair jobs.json with invalid control characters (#3537) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit load_jobs() uses strict json.load() which rejects bare control characters (e.g. literal newlines) in JSON string values. When a cron job prompt contains such characters, the parser throws JSONDecodeError and the function silently returns an empty list — causing ALL scheduled jobs to stop firing with no error logged. Fix: on JSONDecodeError, retry with json.loads(strict=False). If jobs are recovered, auto-rewrite the file with proper escaping via save_jobs() and log a warning. Only fall back to empty list if the JSON is truly unrecoverable. Co-authored-by: Sebastian Bochna --- cron/jobs.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/cron/jobs.py b/cron/jobs.py index 5e3d7067..22c04d0c 100644 --- a/cron/jobs.py +++ b/cron/jobs.py @@ -327,7 +327,20 @@ def load_jobs() -> List[Dict[str, Any]]: with open(JOBS_FILE, 'r', encoding='utf-8') as f: data = json.load(f) return data.get("jobs", []) - except (json.JSONDecodeError, IOError): + except json.JSONDecodeError: + # Retry with strict=False to handle bare control chars in string values + try: + with open(JOBS_FILE, 'r', encoding='utf-8') as f: + data = json.loads(f.read(), strict=False) + jobs = data.get("jobs", []) + if jobs: + # Auto-repair: rewrite with proper escaping + save_jobs(jobs) + logger.warning("Auto-repaired jobs.json (had invalid control characters)") + return jobs + except Exception: + return [] + except IOError: return []