{"record":{"id":"ea75b7463333747c","repo":"HKUDS/Vibe-Trading","slug":"cron-field-part-r-is-not-valid-each-field-must","errorCode":null,"errorMessage":"cron field {part!r} is not valid; each field must be *, */n, or a comma-separated list of numbers and low-high ranges","messagePattern":"cron field (.+?) is not valid; each field must be \\*, \\*/n, or a comma-separated list of numbers and low-high ranges","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/scheduled_research/models.py","lineNumber":57,"sourceCode":"# either end of a range — is validated against these bounds so out-of-range\n# values (e.g. minute ``99``) are rejected. Day-of-week uses the cron\n# convention Sunday == 0; ``7`` is not accepted as a Sunday alias.\nCRON_BOUNDS = ((0, 59), (0, 23), (1, 31), (1, 12), (0, 6))\n\n\ndef _validate_cron_field(part: str, low: int, high: int) -> None:\n    \"\"\"Raise ``ValueError`` when one cron field is malformed or out of range.\"\"\"\n    if part == \"*\":\n        return\n    if _CRON_STEP_RE.fullmatch(part):\n        value = int(part[2:])\n        if not low <= value <= high:\n            raise ValueError(f\"cron field {part!r} is out of range; expected {low}-{high}\")\n        return\n    for atom in part.split(\",\"):\n        match = _CRON_ATOM_RE.fullmatch(atom)\n        if match is None:\n            raise ValueError(\n                f\"cron field {part!r} is not valid; each field must be *, */n, \"\n                f\"or a comma-separated list of numbers and low-high ranges\"\n            )\n        start = int(match.group(1))\n        end = int(match.group(2)) if match.group(2) is not None else start\n        if start > end:\n            raise ValueError(f\"cron range {atom!r} is reversed; expected low-high\")\n        if start < low or end > high:\n            raise ValueError(f\"cron field {atom!r} is out of range; expected {low}-{high}\")\n\n\ndef parse_cron_field(part: str, low: int, high: int) -> Optional[Set[int]]:\n    \"\"\"Expand one validated cron field into its matching values.\n\n    Kept beside :func:`validate_schedule` so the accepted grammar and the\n    executor's evaluation of it can never drift apart.\n\n    Args:","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/scheduled_research/models.py#L39-L75","documentation":"Each cron field must be '*', '*/n', or a comma-separated list of atoms matching a number or low-high range. Anything else — names (MON), L/W flags, @-shorthands, 6-field seconds, or stray characters — fails the atom regex and is rejected by this simplified 5-field parser.","triggerScenarios":"validate_schedule('0 0 * * MON'), '*/5 0 * * 1-5/2', '0 0 * * 1#3', or a Quartz-style '0 0 12 ? * MON-FR' string.","commonSituations":"Copying a cron string from crontab examples, Quartz, or cloud schedulers that support extended syntax; LLM- or user-supplied schedules using day names; assuming seconds fields exist.","solutions":["Convert names to numbers: MON->1, JAN->1, SUN->0 or 7 per your convention (here day-of-week is 0-6).","Remove unsupported flags (@yearly, L, W, #, ?) and extra fields; this parser wants exactly 5 numeric fields.","For fixed intervals, use the milliseconds form instead of cron."],"exampleFix":"# before\nvalidate_schedule('0 0 * * MON-FRI')\n# after\nvalidate_schedule('0 0 * * 1-5')","handlingStrategy":"validation","validationCode":"import re\nCRON_OK = re.compile(r\"^(\\*|(\\*/\\d+)|([0-9]+(-[0-9]+)?)(,[0-9]+(-[0-9]+)*)*)\\s*$\")\ndef fields_shape_ok(s: str) -> bool:\n    parts = s.split()\n    return len(parts) == 5 and all(CRON_OK.fullmatch(p) for p in parts)","typeGuard":"def is_supported_cron(s: str) -> bool:\n    import re\n    atom = r'(\\d+(-\\d+)?)'\n    return bool(re.fullmatch(r'(\\*|\\*/\\d+|' + atom + r'(,' + atom + r')*)', s))","tryCatchPattern":"try:\n    validate_schedule(schedule)\nexcept ValueError as e:\n    raise HTTPError(400, str(e)) from e","preventionTips":["Use numeric cron only: no names, L/W/#/? flags, or @-shorthands.","Translate Quartz 6-field strings to 5 fields before submitting."],"tags":["python","cron","validation","scheduler","regex"],"backgroundTag":"cron-expression-invalid","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}