flowable/flowable-engine · error · FlowableException
Timer needs configuration (either timeDate, timeCycle or tim
Error message
Timer needs configuration (either timeDate, timeCycle or timeDuration is needed) (${id}) What it means
TimerUtil.createTimerEntity requires the timer event definition to define exactly one timing configuration. If, after evaluating timeDate/timeCycle/timeDuration expressions, the resulting timer expression is null, Flowable throws this FlowableException because a timer without any schedule cannot fire.
Source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/util/TimerUtil.java:153
} else if (StringUtils.isNotEmpty(timerEventDefinition.getTimeCycle())) {
businessCalendarRef = CycleBusinessCalendar.NAME;
expression = expressionManager.createExpression(timerEventDefinition.getTimeCycle());
} else if (StringUtils.isNotEmpty(timerEventDefinition.getTimeDuration())) {
businessCalendarRef = DurationBusinessCalendar.NAME;
expression = expressionManager.createExpression(timerEventDefinition.getTimeDuration());
}
if (StringUtils.isNotEmpty(timerEventDefinition.getCalendarName())) {
businessCalendarRef = timerEventDefinition.getCalendarName();
Expression businessCalendarExpression = expressionManager.createExpression(businessCalendarRef);
businessCalendarRef = businessCalendarExpression.getValue(variableContainer).toString();
}
if (expression == null) {
throw new FlowableException(
"Timer needs configuration (either timeDate, timeCycle or timeDuration is needed) (" + timerEventDefinition.getId() + ")");
}
BusinessCalendar businessCalendar = processEngineConfiguration.getBusinessCalendarManager().getBusinessCalendar(businessCalendarRef);
String dueDateString = null;
Date duedate = null;
Object dueDateValue = expression.getValue(variableContainer);
if (dueDateValue instanceof String) {
dueDateString = (String) dueDateValue;
} else if (dueDateValue instanceof Date) {
duedate = (Date) dueDateValue;
} else if (dueDateValue instanceof DateTime) {
JodaDeprecationLogger.LOGGER.warn(
"Using Joda-Time DateTime has been deprecated and will be removed in a future version. Timer event listener expression {} in {} resolved to a Joda-Time DateTime. ",View on GitHub (pinned to d6d39ce1c6)
Solutions
- Add one of <timeDate>, <timeCycle> or <timeDuration> to the timerEventDefinition in the BPMN XML.
- Ensure the referenced expression variable is set so the timer expression resolves to a non-null value.
- Validate the process definition at deployment time (e.g. with a validator or unit test parsing the model) to catch empty timers early.
- If the timer is conditionally needed, model it as a conditional/skip-able path rather than an empty timer definition.
Example fix
// before
<intermediateCatchEvent id="wait"><timerEventDefinition id="t1"/></intermediateCatchEvent>
// after
<intermediateCatchEvent id="wait">
<timerEventDefinition id="t1">
<timeDuration>PT10M</timeDuration>
</timerEventDefinition>
</intermediateCatchEvent> Defensive patterns
Strategy: validation
Validate before calling
boolean timerConfigured(TimerEventDefinition d) {
return StringUtils.isNotEmpty(d.getTimeDate()) || StringUtils.isNotEmpty(d.getTimeCycle()) || StringUtils.isNotEmpty(d.getTimeDuration());
} Try / catch
try { /* deploy/execute process */ } catch (FlowableException e) { if (e.getMessage().startsWith("Timer needs configuration")) log.error("Timer {} missing timeDate/timeCycle/timeDuration", e.getMessage()); else throw e; } Prevention
- Validate BPMN models at deployment with a timer-definition validator
- Keep timeDate/timeCycle/timeDuration under version control and review timer XML in PRs
- Never generate timerEventDefinitions programmatically without setting one timing attribute
When it happens
Trigger: A boundary/intermediate/start timer event whose timeDate, timeCycle and timeDuration attributes are all absent or whose expressions all evaluate to null; createTimerEntity invoked via TimerUtil.timer during execution of such an event.
Common situations: BPMN XML with a timerEventDefinition missing child elements; timer attributes supplied only via deployment-time substitution that silently failed; refactoring that removed the timeDuration value; dynamic model edits leaving an empty timer definition.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- Timer '{activityId}' in {variableScope} was not configured w
- Could not find matching FlowElement for activityId " + activ
- Timer needs configuration (either timeDate, timeCycle or tim
- BPMN XSD could not be found
- The bpmn 2.0 xml is not properly encoded
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/d103247fbf0e0c5f.
Report an issue: GitHub.