flowable/flowable-engine · warning

Timer needs configuration (either timeDate, timeCycle or tim

Error message

Timer needs configuration (either timeDate, timeCycle or timeDuration is needed) ({})

What it means

This warning comes from TimerEventDefinitionParseHandler.createWhen the timer's expression resolves to null, meaning none of timeDate, timeCycle, or timeDuration was configured on the timer event definition. The timer declaration is still created but with a null expression, so it will never fire; the modeled timer is effectively dead. It usually indicates an incomplete or malformed timerEventDefinition in the BPMN XML.

Source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/bpmn/parser/handler/TimerEventDefinitionParseHandler.java:145

            type = TimerDeclarationType.CYCLE;
            expression = expressionManager.createExpression(timerEventDefinition.getTimeCycle());
            // support for endDate
            if (StringUtils.isNotEmpty(timerEventDefinition.getEndDate())) {
                endDate = expressionManager.createExpression(timerEventDefinition.getEndDate());
            }
        } else if (StringUtils.isNotEmpty(timerEventDefinition.getTimeDuration())) {
            // TimeDuration
            type = TimerDeclarationType.DURATION;
            expression = expressionManager.createExpression(timerEventDefinition.getTimeDuration());
        }

        if (StringUtils.isNotEmpty(timerEventDefinition.getCalendarName())) {
            calendarName = expressionManager.createExpression(timerEventDefinition.getCalendarName());
        }

        // neither date, cycle or duration configured!
        if (expression == null) {
            LOGGER.warn("Timer needs configuration (either timeDate, timeCycle or timeDuration is needed) ({})", timerActivity.getId());
        }

        String jobHandlerConfiguration = timerActivity.getId();

        if (jobHandlerType.equalsIgnoreCase(TimerExecuteNestedActivityJobHandler.TYPE) ||
                jobHandlerType.equalsIgnoreCase(TimerCatchIntermediateEventJobHandler.TYPE) ||
                jobHandlerType.equalsIgnoreCase(TimerStartEventJobHandler.TYPE)) {
            jobHandlerConfiguration = TimerStartEventJobHandler.createConfiguration(timerActivity.getId(), endDate, calendarName);
        }

        // Parse the timer declaration
        // TODO move the timer declaration into the bpmn activity or next to the
        // TimerSession
        TimerDeclarationImpl timerDeclaration = new TimerDeclarationImpl(expression, type, jobHandlerType, endDate, calendarName);
        timerDeclaration.setJobHandlerConfiguration(jobHandlerConfiguration);

        timerDeclaration.setExclusive(true);
        return timerDeclaration;

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Add one of <timeDate>, <timeCycle>, or <timeDuration> as a child element of the timerEventDefinition (e.g. <timeDuration>PT1H</timeDuration>).
  2. Check the timer configuration in the modeler: the duration/date/cycle field must actually be saved into the XML.
  3. Ensure ISO-8601 syntax is valid (e.g. PT10M, R/PT1H, 2026-01-01T00:00:00Z).
  4. If the value comes from an expression, verify it is a resolvable expression string like ${timerDuration}.

Example fix

// before
<boundaryEvent id="timerBoundary" attachedToRef="task1">
  <timerEventDefinition/>
</boundaryEvent>
// after
<boundaryEvent id="timerBoundary" attachedToRef="task1">
  <timerEventDefinition>
    <timeDuration>PT1H</timeDuration>
  </timerEventDefinition>
</boundaryEvent>
Defensive patterns

Strategy: validation

Validate before calling

boolean isTimerConfigured(TimerEventDefinition def) {
  return def.getTimeDate() != null
      || def.getTimeCycle() != null
      || def.getTimeDuration() != null;
}

Prevention

When it happens

Trigger: A <timerEventDefinition> element on a boundary event, intermediate catch event, or event subprocess start with no <timeDate>, <timeCycle>, or <timeDuration> child, or where the configured value failed to produce an expression. Raised in createTimer while parsing the definition.

Common situations: Forgot to fill in the duration field in the modeler; the timer XML element is empty; the duration attribute was placed as an XML attribute instead of a child element; a variable-based duration expression that fails to resolve at parse time.

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


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/1e7cff74649b3f39. Report an issue: GitHub.