flowable/flowable-engine · error · FlowableIllegalArgumentException
An end date can only be provided when rescheduling a timer u
Error message
An end date can only be provided when rescheduling a timer using timeDuration.
What it means
RescheduleTimerJobCmd only permits endDate when the timer is rescheduled with a repeating timeCycle... actually per the check: endDate is only allowed when timeCycle == null — but the message says timeDuration. The command throws when endDate != null while timeCycle is null and the caller did not supply a valid single timeDuration setup; effectively endDate is only meaningful for duration-based timers in this API path. It guards against nonsensical schedule combinations.
Source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/RescheduleTimerJobCmd.java:51
private String timeDuration;
private String timeCycle;
private String endDate;
private String calendarName;
public RescheduleTimerJobCmd(String timerJobId, String timeDate, String timeDuration, String timeCycle, String endDate, String calendarName) {
if (timerJobId == null) {
throw new FlowableIllegalArgumentException("The timer job id is mandatory, but 'null' has been provided.");
}
int timeValues = Collections.frequency(Arrays.asList(timeDate, timeDuration, timeCycle), null);
if (timeValues == 0) {
throw new FlowableIllegalArgumentException("A non-null value is required for one of timeDate, timeDuration, or timeCycle");
} else if (timeValues != 2) {
throw new FlowableIllegalArgumentException("At most one non-null value can be provided for timeDate, timeDuration, or timeCycle");
}
if (endDate != null && timeCycle == null) {
throw new FlowableIllegalArgumentException("An end date can only be provided when rescheduling a timer using timeDuration.");
}
this.timerJobId = timerJobId;
this.timeDate = timeDate;
this.timeDuration = timeDuration;
this.timeCycle = timeCycle;
this.endDate = endDate;
this.calendarName = calendarName;
}
@Override
public TimerJobEntity execute(CommandContext commandContext) {
TimerEventDefinition ted = new TimerEventDefinition();
ted.setTimeDate(timeDate);
ted.setTimeDuration(timeDuration);
ted.setTimeCycle(timeCycle);
ted.setEndDate(endDate);
ted.setCalendarName(calendarName);View on GitHub (pinned to d6d39ce1c6)
Solutions
- Remove endDate unless you are rescheduling with timeDuration.
- If you need a bounded repeating timer, express it via timeDuration plus endDate as supported by this command.
- Null the endDate field when passing timeCycle or timeDate.
Example fix
// before new RescheduleTimerJobCmd(jobId, null, "PT1H", "R/PT1H", endDate); // after new RescheduleTimerJobCmd(jobId, null, "PT1H", null, endDate);
Defensive patterns
Strategy: validation
Validate before calling
if (endDate != null && (timeCycle != null || timeDuration == null)) {
throw new IllegalArgumentException("endDate only allowed with timeDuration");
} Try / catch
try {
managementService.rescheduleTimeDurationJob(jobId, duration, endDate);
} catch (FlowableIllegalArgumentException e) {
// drop endDate or switch to duration-based schedule
} Prevention
- Only set endDate together with timeDuration
- Clear endDate when switching schedule modes
- Check API docs for which time field supports end dates
When it happens
Trigger: Executing RescheduleTimerJobCmd with endDate non-null but timeCycle non-null (endDate + cycle), or endDate non-null with timeDate — any combination where the repeat/end semantics are not duration-driven.
Common situations: Developers wanting a timer to stop after a deadline copy the endDate parameter from timer definitions that used ISO 8601 repeat cycles, mixing endDate with timeCycle; or reschedule calls built generically from form data carrying a stale endDate.
Related errors
- At most one non-null value can be provided for timeDate, tim
- batchSize has to be larger than 0
- comment is null
- model is null
- Process definition id or key cannot be null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/bf64f8acd1980a9d.
Report an issue: GitHub.