{"record":{"id":"950a8c662993b46d","repo":"flowable/flowable-engine","slug":"timer-activityid-was-not-configured-with-a-va-950a8c","errorCode":null,"errorMessage":"Timer '${activityId}' was not configured with a valid duration/time, either hand in a java.util.Date or a String in format 'yyyy-MM-dd'T'hh:mm:ss'","messagePattern":"Timer '(.+?)' was not configured with a valid duration/time, either hand in a java\\.util\\.Date or a String in format 'yyyy-MM-dd'T'hh:mm:ss'","errorType":"exception","errorClass":"ActivitiException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/persistence/entity/TimerJobEntity.java","lineNumber":231,"sourceCode":"                        .getBusinessCalendar(getBusinessCalendarName(TimerEventHandler.geCalendarNameFromConfiguration(jobHandlerConfiguration)));\n\n                VariableScope executionEntity = null;\n                if (executionId != null) {\n                    executionEntity = commandContext.getExecutionEntityManager().findExecutionById(executionId);\n                }\n\n                if (executionEntity == null) {\n                    executionEntity = NoExecutionVariableScope.getSharedInstance();\n                }\n\n                if (endDateExpression != null) {\n                    Object endDateValue = endDateExpression.getValue(executionEntity);\n                    if (endDateValue instanceof String) {\n                        endDateString = (String) endDateValue;\n                    } else if (endDateValue instanceof Date) {\n                        endDate = (Date) endDateValue;\n                    } else {\n                        throw new ActivitiException(\"Timer '\" + ((ExecutionEntity) executionEntity).getActivityId()\n                                + \"' was not configured with a valid duration/time, either hand in a java.util.Date or a String in format 'yyyy-MM-dd'T'hh:mm:ss'\");\n                    }\n\n                    if (endDate == null) {\n                        endDate = businessCalendar.resolveEndDate(endDateString);\n                    }\n                }\n            }\n        }\n\n        if (processDefinitionId != null) {\n            ProcessDefinition def = Context.getProcessEngineConfiguration().getRepositoryService().getProcessDefinition(processDefinitionId);\n            maxIterations = checkStartEventDefinitions(def, embededActivityId);\n            if (maxIterations <= 1) {\n                maxIterations = checkBoundaryEventsDefinitions(def, embededActivityId);\n            }\n        } else {\n            maxIterations = 1;","sourceCodeStart":213,"sourceCodeEnd":249,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/persistence/entity/TimerJobEntity.java#L213-L249","documentation":"TimerJobEntity.restoreExtraData evaluates the timer's end-date expression when re-creating a timer (e.g. after restart or when scheduling repeating timers). The expression must evaluate to a java.util.Date or a String parseable by the business calendar; any other type makes the engine throw this ActivitiException naming the activity. It protects the job store from an unparseable due date.","triggerScenarios":"A boundary/intermediate timer's timeDate/timeDuration/timeCycle endDate expression evaluates to a type other than Date or String (e.g. Integer, Long, or a custom object) when the timer job is restored or scheduled by execute/scheduleNewTimer.","commonSituations":"Process variable passed into a timer endDate expression has the wrong type (number instead of ISO date string or Date); expression returns a Joda/Java-8 type the engine doesn't recognize; Activiti 5→Flowable migration where variable types changed; expression misconfigured in BPMN XML.","solutions":["Make the expression return a java.util.Date or an ISO-8601 'yyyy-MM-dd'T'hh:mm:ss' String","Convert the variable at process start (store as Date or formatted String) instead of at timer evaluation time","Fix the expression in the BPMN XML (e.g. ${endDate} → ${endDateAsString} backed by a correctly typed variable)","Check for type changes after engine/version migration and re-deploy with corrected models"],"exampleFix":"// before: variable is a timestamp long\nruntimeService.startProcessInstanceByKey(\"p\", vars); // vars: endDate = 1727000000L\n// after\nSimpleDateFormat fmt = new SimpleDateFormat(\"yyyy-MM-dd'T'HH:mm:ss\");\nvars.put(\"endDate\", fmt.format(new Date(1727000000L * 1000)));\nruntimeService.startProcessInstanceByKey(\"p\", vars);","handlingStrategy":"validation","validationCode":"Object v = vars.get(\"endDate\");\nboolean ok = v instanceof java.util.Date || v instanceof String; // String must be ISO yyyy-MM-dd'T'HH:mm:ss","typeGuard":"boolean isValidTimerValue(Object v) {\n    return v instanceof java.util.Date || v instanceof String;\n}","tryCatchPattern":null,"preventionTips":["Store timer inputs as Date or ISO-8601 strings only","Validate expression result types when authoring BPMN models","Re-check timer expressions after engine upgrades/migrations"],"tags":["timer","job","date","bpmn"],"backgroundTag":"invalid-duration-format","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}