{"record":{"id":"1e7cff74649b3f39","repo":"flowable/flowable-engine","slug":"timer-needs-configuration-either-timedate-timecy-1e7cff","errorCode":null,"errorMessage":"Timer needs configuration (either timeDate, timeCycle or timeDuration is needed) ({})","messagePattern":"Timer needs configuration \\(either timeDate, timeCycle or timeDuration is needed\\) \\((.+?)\\)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/bpmn/parser/handler/TimerEventDefinitionParseHandler.java","lineNumber":145,"sourceCode":"            type = TimerDeclarationType.CYCLE;\n            expression = expressionManager.createExpression(timerEventDefinition.getTimeCycle());\n            // support for endDate\n            if (StringUtils.isNotEmpty(timerEventDefinition.getEndDate())) {\n                endDate = expressionManager.createExpression(timerEventDefinition.getEndDate());\n            }\n        } else if (StringUtils.isNotEmpty(timerEventDefinition.getTimeDuration())) {\n            // TimeDuration\n            type = TimerDeclarationType.DURATION;\n            expression = expressionManager.createExpression(timerEventDefinition.getTimeDuration());\n        }\n\n        if (StringUtils.isNotEmpty(timerEventDefinition.getCalendarName())) {\n            calendarName = expressionManager.createExpression(timerEventDefinition.getCalendarName());\n        }\n\n        // neither date, cycle or duration configured!\n        if (expression == null) {\n            LOGGER.warn(\"Timer needs configuration (either timeDate, timeCycle or timeDuration is needed) ({})\", timerActivity.getId());\n        }\n\n        String jobHandlerConfiguration = timerActivity.getId();\n\n        if (jobHandlerType.equalsIgnoreCase(TimerExecuteNestedActivityJobHandler.TYPE) ||\n                jobHandlerType.equalsIgnoreCase(TimerCatchIntermediateEventJobHandler.TYPE) ||\n                jobHandlerType.equalsIgnoreCase(TimerStartEventJobHandler.TYPE)) {\n            jobHandlerConfiguration = TimerStartEventJobHandler.createConfiguration(timerActivity.getId(), endDate, calendarName);\n        }\n\n        // Parse the timer declaration\n        // TODO move the timer declaration into the bpmn activity or next to the\n        // TimerSession\n        TimerDeclarationImpl timerDeclaration = new TimerDeclarationImpl(expression, type, jobHandlerType, endDate, calendarName);\n        timerDeclaration.setJobHandlerConfiguration(jobHandlerConfiguration);\n\n        timerDeclaration.setExclusive(true);\n        return timerDeclaration;","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/bpmn/parser/handler/TimerEventDefinitionParseHandler.java#L127-L163","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Add one of <timeDate>, <timeCycle>, or <timeDuration> as a child element of the timerEventDefinition (e.g. <timeDuration>PT1H</timeDuration>).","Check the timer configuration in the modeler: the duration/date/cycle field must actually be saved into the XML.","Ensure ISO-8601 syntax is valid (e.g. PT10M, R/PT1H, 2026-01-01T00:00:00Z).","If the value comes from an expression, verify it is a resolvable expression string like ${timerDuration}."],"exampleFix":"// before\n<boundaryEvent id=\"timerBoundary\" attachedToRef=\"task1\">\n  <timerEventDefinition/>\n</boundaryEvent>\n// after\n<boundaryEvent id=\"timerBoundary\" attachedToRef=\"task1\">\n  <timerEventDefinition>\n    <timeDuration>PT1H</timeDuration>\n  </timerEventDefinition>\n</boundaryEvent>","handlingStrategy":"validation","validationCode":"boolean isTimerConfigured(TimerEventDefinition def) {\n  return def.getTimeDate() != null\n      || def.getTimeCycle() != null\n      || def.getTimeDuration() != null;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always fill timeDate, timeCycle or timeDuration when adding a timer event","Validate exported BPMN XML for empty timerEventDefinition elements before deployment","Use modeler form validation to require a timer value","Test timers in a staging deployment and check for parser warnings in logs"],"tags":["bpmn","parser","timer","flowable"],"backgroundTag":"missing-required-config-field","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}