fix(cron): guard load_jobs against malformed jobs.json shapes#23002
fix(cron): guard load_jobs against malformed jobs.json shapes#23002KhanCold wants to merge 1 commit into
Conversation
Review: Tests read source from a hardcoded
|
…search#22569) cron.jobs.load_jobs called data.get("jobs", []) immediately after json.load(), assuming the root is always a dict. If jobs.json is hand-edited or written by a legacy release in a non-dict shape (bare list, null, scalar, string), the call crashes with AttributeError. Changes: - Guard both json.load() and json.loads(strict=False) paths with isinstance(data, dict) checks. - If data is a bare list (legacy format), auto-migrate by calling save_jobs() and return the list. - If data is any other non-dict shape, log an error and return [] instead of crashing. Fixes NousResearch#22569
cc94667 to
6491bf9
Compare
|
Thanks for the review. The test file in this PR ( The examples in your review appear to reference other PRs. If there are specific changes needed in this PR, please let me know and I'll address them promptly. |
|
Hi @liuhao1024 — I replied to your review above confirming that the hardcoded path concern does not apply to this PR (it uses tempfile for isolation). If everything looks good, would appreciate a review or approval. Thanks! 🙏 |
Summary
Fixes #22569.
cron.jobs.load_jobscalleddata.get("jobs", [])immediately afterjson.load(), assuming the parsed root is always adict. Ifjobs.jsonis hand-edited or written by a legacy release in any non-dict shape — a bare list ([{"id": "x"}]),null, a scalar, or a string — the call crashes withAttributeError.Changes
json.load()andjson.loads(strict=False)fallback paths withisinstance(data, dict)checks.datais a bare list (legacy format), auto-migrate by callingsave_jobs()and return the list.datais any other non-dict shape, log an error and return[]instead of crashing.Test Plan
Added regression tests in
tests/cron/test_cron_load_jobs_malformed.pycovering:nullroot → empty listpython3 -m unittest tests.cron.test_cron_load_jobs_malformed -v # 6 passed