{"record":{"id":"c364fefa7d8a7537","repo":"Activiti/Activiti","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":"activiti-core/activiti-engine/src/main/java/org/activiti/engine/impl/calendar/CronExpression.java","lineNumber":246,"sourceCode":"     * @throws java.text.ParseException\n     *           if the string expression cannot be parsed into a valid <CODE>CronExpression</CODE>\n     */\n    public CronExpression(String cronExpression, ClockReader clockReader, TimeZone timeZone) throws ParseException {\n        this(cronExpression, clockReader);\n        this.timeZone = timeZone;\n    }\n\n    /**\n     * Constructs a new <CODE>CronExpression</CODE> based on the specified parameter.\n     *\n     * @param cronExpression\n     *          String representation of the cron expression the new object should represent\n     * @throws java.text.ParseException\n     *           if the string expression cannot be parsed into a valid <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.clockReader = clockReader;\n        this.cronExpression = cronExpression.toUpperCase(Locale.US);\n\n        buildExpression(this.cronExpression);\n    }\n\n    /**\n     * Returns the time zone for which this <code>CronExpression</code> will be resolved.\n     */\n    public TimeZone getTimeZone() {\n        if (timeZone == null) {\n            timeZone = clockReader.getCurrentTimeZone();\n        }\n\n        return timeZone;\n    }","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/Activiti/Activiti/blob/56435b1a97deeafdc09dd40074b056c89fba5a8a/activiti-core/activiti-engine/src/main/java/org/activiti/engine/impl/calendar/CronExpression.java#L228-L264","documentation":"The CronExpression(String, ClockReader) constructor explicitly rejects a null cron expression string with IllegalArgumentException('cronExpression cannot be null'). This is a fail-fast contract check before any parsing happens. Any scheduler setup that passes a null expression hits this immediately.","triggerScenarios":"Calling `new CronExpression(null, clockReader)` (or the two-arg variant used by AdvancedSchedulerResolverWithTimeZone at CronExpression.java:246) when the duedateDescription/timeCycle value resolved from process configuration or variables is null.","commonSituations":"BPMN timer with a missing or empty timeCycle element yielding null; a process variable feeding the timer expression not set at runtime; configuration key renamed/removed so the lookup returns null; deserialized timer definitions losing the expression field.","solutions":["Ensure the timer timeCycle/duedateDescription value is non-null before constructing the calendar or CronExpression.","Add a null/blank check with a clear error at the configuration-loading layer.","Fix the source of the null: missing BPMN timeCycle element, unset process variable, or missing config entry.","Provide a default schedule expression when configuration is absent, if a fallback is acceptable."],"exampleFix":"// before\nCronExpression ce = new CronExpression(cfg.getString(\"timer.cron\"), clockReader); // may be null\n// after\nString cron = cfg.getString(\"timer.cron\");\nif (cron == null || cron.trim().isEmpty()) throw new IllegalStateException(\"timer.cron must be set\");\nCronExpression ce = new CronExpression(cron, clockReader);","handlingStrategy":"validation","validationCode":"Objects.requireNonNull(cronExpression, \"cronExpression cannot be null\");\nif (cronExpression.trim().isEmpty()) throw new IllegalArgumentException(\"cronExpression cannot be empty\");","typeGuard":"boolean hasCron(TimerDefinition def) { return def != null && def.getTimeCycle() != null && !def.getTimeCycle().trim().isEmpty(); }","tryCatchPattern":"try {\n    return new CronExpression(expr, clockReader);\n} catch (IllegalArgumentException | ParseException e) {\n    throw new IllegalArgumentException(\"timer cron not configured/valid: \" + e.getMessage(), e);\n}","preventionTips":["Default missing timer config explicitly at load time rather than letting null flow through.","Assert non-null timeCycle in BPMN model validation at deployment.","Fail fast in configuration parsing, not deep in the scheduler.","Log which timer/process element had the missing expression."],"tags":["java","cron","null-check","scheduler","activiti"],"backgroundTag":"null-argument","analyzedSha":"56435b1a97deeafdc09dd40074b056c89fba5a8a","analyzedAt":"2026-09-09T21:00:06.703Z","contentChangedAt":"2026-09-09T21:00:06.703Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}