{"record":{"id":"2ab9ef63ae14c1d1","repo":"flowable/flowable-engine","slug":"cronexpression-cannot-be-null","errorCode":null,"errorMessage":"cronExpression cannot be null","messagePattern":"cronExpression cannot be null","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/calendar/CronExpression.java","lineNumber":282,"sourceCode":"    \n    private ClockReader clockReader;\n\n    /**\n     * Constructs a new <CODE>CronExpression</CODE> based on the specified\n     * parameter.\n     * \n     * @param cronExpression\n     *            String representation of the cron expression the new object\n     *            should represent\n     * @param clockReader\n     *            The reader which will provide the current time\n     * @throws java.text.ParseException\n     *             if the string expression cannot be parsed into a valid\n     *             <CODE>CronExpression</CODE>\n     */\n    public CronExpression(String cronExpression, ClockReader clockReader) throws ParseException {\n        if (cronExpression == null) {\n            throw new IllegalArgumentException(\"cronExpression cannot be null\");\n        }\n\n        this.cronExpression = cronExpression.toUpperCase(Locale.US);\n        this.clockReader = clockReader;\n\n        buildExpression(this.cronExpression);\n    }\n\n    /**\n     * Constructs a new {@code CronExpression} as a copy of an existing\n     * instance.\n     * \n     * @param expression\n     *            The existing cron expression to be copied\n     */\n    public CronExpression(CronExpression expression, ClockReader clockReader) {\n        /*\n         * We don't call the other constructor here since we need to swallow the","sourceCodeStart":264,"sourceCodeEnd":300,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/calendar/CronExpression.java#L264-L300","documentation":"The CronExpression constructor throws IllegalArgumentException immediately when the cronExpression string argument is null. The library deliberately fails fast because a null expression cannot be meaningful; note this is a RuntimeException, unlike the ParseException thrown for malformed (non-null) strings.","triggerScenarios":"Passing null as the first argument to new CronExpression(cronExpression, clockReader), typically when a timer/duedate string was never set on the job or process definition (null field value propagated down).","commonSituations":"BPMN timer definitions with a missing/empty timeDate element resolved to null; programmatic job creation where the duedate string was not set; database rows with NULL duedate columns loaded by a job executor.","solutions":["Ensure the timer/duedate string is set before constructing CronExpression; check the source of the null (BPMN XML attribute, DB column)","Add an explicit null/empty check on the duedate string in caller code and fail with a descriptive error or skip the job","Guard with a default expression if a missing schedule is acceptable","If data is corrupted, fix the stored job/timer definition row to contain a valid expression"],"exampleFix":"// before\nCronExpression ce = new CronExpression(job.getDuedate(), clockReader); // may be null\n// after\nif (job.getDuedate() == null || job.getDuedate().trim().isEmpty()) {\n    throw new FlowableException(\"Job \" + job.getId() + \" has no duedate configured\");\n}\nCronExpression ce = new CronExpression(job.getDuedate(), clockReader);","handlingStrategy":"type-guard","validationCode":"if (duedate == null || duedate.trim().isEmpty()) {\n    throw new IllegalArgumentException(\"cron expression must be non-null and non-empty\");\n}","typeGuard":"boolean hasCron(com.example.Job j) { return j != null && j.getDuedate() != null && !j.getDuedate().isBlank(); }","tryCatchPattern":"try {\n    CronExpression ce = new CronExpression(expr, clockReader);\n} catch (IllegalArgumentException | ParseException e) {\n    logger.error(\"Cannot build cron from '{}'\", expr, e);\n}","preventionTips":["Null-check duedate strings loaded from DB/BPMN before constructing CronExpression","Enforce NOT NULL + non-empty constraints on duedate columns","Fail fast at definition-parse time when a timer has no timeDate value"],"tags":["cron","null-check","flowable","configuration"],"backgroundTag":"null-argument","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}