{"record":{"id":"bec021ed12de62c9","repo":"HKUDS/DeepTutor","slug":"invalid-cron-expression-schedule-expr-r-exc","errorCode":null,"errorMessage":"invalid cron expression {schedule.expr!r}: {exc}","messagePattern":"invalid cron expression (.+?): (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"deeptutor/services/cron/service.py","lineNumber":146,"sourceCode":"        return now_ms + schedule.every_seconds * 1000\n\n    if schedule.kind == \"cron\" and schedule.expr:\n        try:\n            from zoneinfo import ZoneInfo\n\n            from croniter import croniter\n\n            tz = ZoneInfo(schedule.tz) if schedule.tz else datetime.now().astimezone().tzinfo\n            base = datetime.fromtimestamp(now_ms / 1000, tz=tz)\n            next_dt = croniter(schedule.expr, base).get_next(datetime)\n            return int(next_dt.timestamp() * 1000)\n        except ImportError:\n            raise ValueError(\n                \"cron expressions need the 'croniter' package — \"\n                \"use an 'every' or 'at' schedule instead\"\n            ) from None\n        except Exception as exc:\n            raise ValueError(f\"invalid cron expression {schedule.expr!r}: {exc}\") from None\n\n    return None\n\n\ndef validate_schedule(schedule: CronSchedule) -> None:\n    \"\"\"Reject schedules that could never run (raises ValueError).\"\"\"\n    if schedule.kind == \"at\":\n        if not schedule.at_ms:\n            raise ValueError(\"'at' schedules need a time\")\n        if schedule.at_ms <= _now_ms():\n            raise ValueError(\"'at' time is in the past\")\n        return\n    if schedule.kind == \"every\":\n        if not schedule.every_seconds or schedule.every_seconds < 30:\n            raise ValueError(\"'every' interval must be at least 30 seconds\")\n        return\n    if schedule.kind == \"cron\":\n        if schedule.tz:","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/HKUDS/DeepTutor/blob/3e82f130422a813cdd73c10b21a44e9325f5821a/deeptutor/services/cron/service.py#L128-L164","documentation":"compute_next_run wraps croniter evaluation in a broad except and re-raises any parsing/evaluation failure as ValueError including the offending expression and underlying cause. Invalid or unsupportable cron strings fail fast at validation time rather than at fire time.","triggerScenarios":"Passing a malformed expression like CronSchedule(kind=\"cron\", expr=\"99 * * *\") or \"* * *\" (wrong field count) to add_job or validate_schedule.","commonSituations":"Typos in hand-written cron strings; converting 5-field to 6-field/Quartz syntax; unsanitized user-supplied cron input from forms or chat commands.","solutions":["Fix the expression to standard 5-field cron syntax (minute hour day month weekday)","Validate user input with croniter.croniter(expr, datetime.now()) before calling add_job","Log schedule.expr on failure to identify which job config is broken"],"exampleFix":"# before\nexpr = \"0 9 * * *\" + user_input  # concatenated garbage\njob = svc.add_job(CronSchedule(kind=\"cron\", expr=expr), ...)\n# after\nfrom croniter import croniter\ntry:\n    croniter(user_input, datetime.now())\n    expr = user_input\nexcept Exception:\n    expr = \"0 9 * * *\"\njob = svc.add_job(CronSchedule(kind=\"cron\", expr=expr), ...)","handlingStrategy":"validation","validationCode":"from datetime import datetime\nfrom croniter import croniter\n\ndef valid_cron(expr: str) -> bool:\n    try:\n        croniter(expr, datetime.now())\n        return True\n    except Exception:\n        return False\n\nassert valid_cron(schedule.expr), f\"bad cron: {schedule.expr!r}\"","typeGuard":null,"tryCatchPattern":"try:\n    svc.add_job(schedule, ...)\nexcept ValueError as e:\n    if \"invalid cron expression\" in str(e):\n        log.warning(\"rejecting cron %r\", schedule.expr)\n        return error_response(str(e))\n    raise","preventionTips":["Validate cron strings at the API boundary with croniter","Never concatenate/build cron strings from unvalidated parts","Fuzz-test generated expressions in CI"],"tags":["cron","validation","scheduling"],"backgroundTag":"cron-expression-invalid","analyzedSha":"3e82f130422a813cdd73c10b21a44e9325f5821a","analyzedAt":"2026-08-27T06:57:25.364Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}