Activiti/Activiti · error · IllegalArgumentException

cronExpression cannot be null

Error message

cronExpression cannot be null

What it means

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.

Solutions

  1. Ensure the timer timeCycle/duedateDescription value is non-null before constructing the calendar or CronExpression.
  2. Add a null/blank check with a clear error at the configuration-loading layer.
  3. Fix the source of the null: missing BPMN timeCycle element, unset process variable, or missing config entry.
  4. Provide a default schedule expression when configuration is absent, if a fallback is acceptable.

Example fix

// before
CronExpression ce = new CronExpression(cfg.getString("timer.cron"), clockReader); // may be null
// after
String cron = cfg.getString("timer.cron");
if (cron == null || cron.trim().isEmpty()) throw new IllegalStateException("timer.cron must be set");
CronExpression ce = new CronExpression(cron, clockReader);
Defensive patterns

Strategy: validation

Validate before calling

Objects.requireNonNull(cronExpression, "cronExpression cannot be null");
if (cronExpression.trim().isEmpty()) throw new IllegalArgumentException("cronExpression cannot be empty");

Type guard

boolean hasCron(TimerDefinition def) { return def != null && def.getTimeCycle() != null && !def.getTimeCycle().trim().isEmpty(); }

Try / catch

try {
    return new CronExpression(expr, clockReader);
} catch (IllegalArgumentException | ParseException e) {
    throw new IllegalArgumentException("timer cron not configured/valid: " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of Activiti/Activiti@56435b1a97 (2026-09-09). Data as JSON: /api/errors/c364fefa7d8a7537. Report an issue: GitHub.

Appendix: source

Thrown at activiti-core/activiti-engine/src/main/java/org/activiti/engine/impl/calendar/CronExpression.java:246

     * @throws java.text.ParseException
     *           if the string expression cannot be parsed into a valid <CODE>CronExpression</CODE>
     */
    public CronExpression(String cronExpression, ClockReader clockReader, TimeZone timeZone) throws ParseException {
        this(cronExpression, clockReader);
        this.timeZone = timeZone;
    }

    /**
     * Constructs a new <CODE>CronExpression</CODE> based on the specified parameter.
     *
     * @param cronExpression
     *          String representation of the cron expression the new object should represent
     * @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.clockReader = clockReader;
        this.cronExpression = cronExpression.toUpperCase(Locale.US);

        buildExpression(this.cronExpression);
    }

    /**
     * Returns the time zone for which this <code>CronExpression</code> will be resolved.
     */
    public TimeZone getTimeZone() {
        if (timeZone == null) {
            timeZone = clockReader.getCurrentTimeZone();
        }

        return timeZone;
    }

View on GitHub (pinned to 56435b1a97)