Activiti/Activiti · error · ActivitiException
Timer needs configuration (either timeDate, timeCycle or…
Error message
Timer needs configuration (either timeDate, timeCycle or timeDuration is needed) (" + timerEventDefinition.getId() + ") What it means
TimerUtil.createTimerEntityForTimerEventDefinition throws ActivitiException when a BPMN timer event definition resolves to a null expression — meaning none of timeDate, timeCycle, or timeDuration yielded a value. Activiti cannot schedule a timer without one of these.
Solutions
- Add a <timeDate>, <timeCycle> or <timeDuration> child to the timerEventDefinition in the BPMN XML
- If the timer uses an expression like ${timeout}, ensure that variable has a value before the timer node executes
- Set a process variable default (e.g. via an initialization listener or start form) so the expression never resolves to null
Example fix
// before <intermediateCatchEvent id="wait"><timerEventDefinition id="td"/></intermediateCatchEvent> // after <intermediateCatchEvent id="wait"><timerEventDefinition id="td"><timeDuration>PT10M</timeDuration></timerEventDefinition></intermediateCatchEvent>
Defensive patterns
Strategy: validation
Validate before calling
// BPMN check
if (!xml.contains("timeDate") && !xml.contains("timeCycle") && !xml.contains("timeDuration")) throw new IllegalArgumentException("timerEventDefinition needs timeDate/timeCycle/timeDuration"); Try / catch
try { runtimeService.startProcessInstanceByKey(key, vars); } catch (ActivitiException e) { if (e.getMessage().contains("Timer needs configuration")) { /* fix BPMN or missing variable */ } throw e; } Prevention
- Always include one of timeDate/timeCycle/timeDuration in timer event definitions
- If timer values come from variables, initialize defaults at process start
- Validate BPMN XML with the model API before deployment
When it happens
Trigger: A boundary/intermediate timer event or timer start event whose <timeDate>/<timeCycle>/<timeDuration> element is missing, or whose expression evaluates to null (e.g. an expression referencing an empty/unset process variable).
Common situations: BPMN XML hand-edited and timer child element removed; timer duration supplied via a process variable that was never set (e.g. ${timeoutDuration} is null at runtime).
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
- doesn't implement
- doesn't implement
- Failed to parse cron expression:
- 'html' or 'text' is required to be defined when using the…
- No process validator defined
AI-assisted analysis of Activiti/Activiti@56435b1a97 (2026-09-09).
Data as JSON: /api/errors/085a590ac284a743.
Report an issue: GitHub.
Appendix: source
Thrown at activiti-core/activiti-engine/src/main/java/org/activiti/engine/impl/util/TimerUtil.java:88
if (StringUtils.isNotEmpty(timerEventDefinition.getTimeDate())) {
businessCalendarRef = DueDateBusinessCalendar.NAME;
expression = expressionManager.createExpression(timerEventDefinition.getTimeDate());
} 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(scopeForExpression).toString();
}
if (expression == null) {
throw new ActivitiException(
"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(scopeForExpression);
if (dueDateValue instanceof String) {
dueDateString = (String) dueDateValue;
} else if (dueDateValue instanceof Date) {
duedate = (Date) dueDateValue;View on GitHub (pinned to 56435b1a97)