flowable/flowable-engine · error · IllegalArgumentException
cronExpression cannot be null
Error message
cronExpression cannot be null
What it means
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.
Source
Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/calendar/CronExpression.java:282
private ClockReader clockReader;
/**
* Constructs a new <CODE>CronExpression</CODE> based on the specified
* parameter.
*
* @param cronExpression
* String representation of the cron expression the new object
* should represent
* @param clockReader
* The reader which will provide the current time
* @throws java.text.ParseException
* if the string expression cannot be parsed into a valid
* <CODE>CronExpression</CODE>
*/
public CronExpression(String cronExpression, ClockReader clockReader) throws ParseException {
if (cronExpression == null) {
throw new IllegalArgumentException("cronExpression cannot be null");
}
this.cronExpression = cronExpression.toUpperCase(Locale.US);
this.clockReader = clockReader;
buildExpression(this.cronExpression);
}
/**
* Constructs a new {@code CronExpression} as a copy of an existing
* instance.
*
* @param expression
* The existing cron expression to be copied
*/
public CronExpression(CronExpression expression, ClockReader clockReader) {
/*
* We don't call the other constructor here since we need to swallow theView on GitHub (pinned to d6d39ce1c6)
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
Example fix
// before
CronExpression ce = new CronExpression(job.getDuedate(), clockReader); // may be null
// after
if (job.getDuedate() == null || job.getDuedate().trim().isEmpty()) {
throw new FlowableException("Job " + job.getId() + " has no duedate configured");
}
CronExpression ce = new CronExpression(job.getDuedate(), clockReader); Defensive patterns
Strategy: type-guard
Validate before calling
if (duedate == null || duedate.trim().isEmpty()) {
throw new IllegalArgumentException("cron expression must be non-null and non-empty");
} Type guard
boolean hasCron(com.example.Job j) { return j != null && j.getDuedate() != null && !j.getDuedate().isBlank(); } Try / catch
try {
CronExpression ce = new CronExpression(expr, clockReader);
} catch (IllegalArgumentException | ParseException e) {
logger.error("Cannot build cron from '{}'", expr, e);
} Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- Failed to parse scheduler expression:
- no org.flowable.app.engine.AppEngine defined in the applicat
- transactionManager is required property for SpringAppEngineC
- categoryLike is null
- categoryNotEquals is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/2ab9ef63ae14c1d1.
Report an issue: GitHub.