{"record":{"id":"8309a70c97d8a4ab","repo":"flowable/flowable-engine","slug":"timer-expression","errorCode":null,"errorMessage":"Timer expression ","messagePattern":"Timer expression ","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/RescheduleTimerJobCmd.java","lineNumber":120,"sourceCode":"                isRepeating = true;\n\n            } else {\n\n                // Try to parse as ISO8601 first\n                try {\n                    timerDueDate = DateUtil.parseDate(newDateValue);\n                } catch (Exception e) { }\n\n                // Try to parse as cron expression\n                try {\n                    timerDueDate = businessCalendarManager.getBusinessCalendar(CycleBusinessCalendar.NAME).resolveDuedate(newDateValue);\n                    isRepeating = true;\n\n                } catch (Exception pe) { }\n            }\n            \n            if (timerDueDate == null) {\n                throw new FlowableException(\"Timer expression '\" + newDateValue + \"' did not resolve to java.util.Date for \" + planItemInstance);\n            }\n        }\n        \n        CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);\n        JobServiceConfiguration jobServiceConfiguration = cmmnEngineConfiguration.getJobServiceConfiguration();\n        \n        TimerJobEntity newTimer = timerJobService.createTimerJob();\n        newTimer.setJobType(timerJob.getJobType());\n        newTimer.setJobHandlerType(timerJob.getJobHandlerType());\n        newTimer.setExclusive(true);\n        newTimer.setRetries(jobServiceConfiguration.getAsyncExecutorNumberOfRetries());\n        newTimer.setDuedate(timerDueDate);\n        newTimer.setScopeDefinitionId(timerJob.getScopeDefinitionId());\n        newTimer.setScopeId(timerJob.getScopeId());\n        newTimer.setSubScopeId(timerJob.getSubScopeId());\n        newTimer.setCategory(timerJob.getCategory());\n        newTimer.setScopeType(timerJob.getScopeType());\n        newTimer.setElementId(timerJob.getElementId());","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/RescheduleTimerJobCmd.java#L102-L138","documentation":"When rescheduling a timer, the command evaluates the new date expression. If the resolved value is not a java.util.Date (neither a literal Date nor a parseable expression result), it throws FlowableException saying the timer expression did not resolve to a Date.","triggerScenarios":"Passing a new due date as a String expression like '${someDate}' whose variable is missing or not a Date; passing a formatted string not parseable as ISO date; passing an unsupported type (Long, Instant) through the expression.","commonSituations":"Setting a process/case variable used by the timer expression to a String instead of Date; typos in date format; using java.time types that Flowable's CMMN timer expression resolver does not accept.","solutions":["Ensure the referenced variable is a java.util.Date before rescheduling","Pass a Date object directly instead of a string/expression","Use an ISO-8601 parseable string if a string must be supplied","Log and inspect the exception's 'pe' cause by evaluating the expression manually in a test"],"exampleFix":"// before\ncmmnRuntimeService.setTimerJobDueDate(jobId, \"${dueDateString}\"); // variable is a String\n// after\nDate due = new SimpleDateFormat(\"yyyy-MM-dd\").parse(\"2026-10-01\");\ncmmnRuntimeService.setTimerJobDueDate(jobId, due);","handlingStrategy":"validation","validationCode":"Object v = caseVariables.get(\"dueDateVar\");\nif (!(v instanceof java.util.Date)) throw new IllegalArgumentException(\"timer var must be java.util.Date\");","typeGuard":"boolean isResolvableDate(Object v) { return v instanceof java.util.Date; }","tryCatchPattern":"try { runtimeService.setTimerJobDueDate(jobId, due); } catch (FlowableException e) { log.error(\"Timer expression did not resolve to Date\", e); }","preventionTips":["Store timer variables as java.util.Date","Prefer passing literal Date objects","Test expressions resolving to null"],"tags":["cmmn","timer-expression","type-mismatch"],"backgroundTag":"invalid-date-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"}