{"record":{"id":"b3c20b7ae8d8bd45","repo":"flowable/flowable-engine","slug":"duedate-is-null","errorCode":null,"errorMessage":"duedate is null","messagePattern":"duedate is null","errorType":"validation","errorClass":"ActivitiIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/persistence/entity/JobEntityManager.java","lineNumber":57,"sourceCode":"\n/**\n * @author Tom Baeyens\n * @author Daniel Meyer\n * @author Joram Barrez\n */\npublic class JobEntityManager extends AbstractManager {\n\n    public void send(JobEntity message) {\n        message.insert();\n        if (Context.getProcessEngineConfiguration().getAsyncExecutor().isActive()) {\n            hintAsyncExecutor(message);\n        }\n    }\n\n    public void schedule(TimerJobEntity timer) {\n        Date duedate = timer.getDuedate();\n        if (duedate == null) {\n            throw new ActivitiIllegalArgumentException(\"duedate is null\");\n        }\n\n        timer.insert();\n    }\n\n    protected void hintAsyncExecutor(Job job) {\n\n        AsyncExecutor asyncExecutor = Context.getProcessEngineConfiguration().getAsyncExecutor();\n        CommandContext commandContext = CommandContextUtil.getCommandContext();\n\n        TransactionContext transactionContext = org.flowable.common.engine.impl.context.Context.getTransactionContext();\n        if (transactionContext != null) {\n            JobAddedTransactionListener jobAddedTransactionListener = new JobAddedTransactionListener(job, asyncExecutor,\n                CommandContextUtil.getProcessEngineConfiguration(commandContext).getCommandExecutor());\n            transactionContext.addTransactionListener(TransactionState.COMMITTED, jobAddedTransactionListener);\n\n        } else {\n            CommandContextCloseListener commandContextCloseListener = new AsyncJobAddedNotification(job, asyncExecutor);","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/persistence/entity/JobEntityManager.java#L39-L75","documentation":"JobEntityManager.schedule persists a timer job and requires a valid due date, since the async executor depends on it to decide when to fire. A timer with a null duedate is rejected with ActivitiIllegalArgumentException before insertion.","triggerScenarios":"Programmatically creating a TimerJobEntity and calling schedule without setting duedate; a boundary/intermediate timer event whose timeDuration/timeDate expression evaluated to null; custom job creation code copied from examples and partially filled.","commonSituations":"BPMN timer events using an expression variable that resolves to null at runtime (unset process variable); custom schedulers building timer entities manually; migrating job definitions where the due-date column/logic was dropped.","solutions":["Ensure the timer definition provides a valid timeDate/timeDuration/timeCycle expression and that referenced process variables are set.","Set duedate explicitly (e.g., new Date(System.currentTimeMillis() + delay)) before calling schedule.","Validate/parse the timer expression at deployment time so failures surface at deploy, not runtime."],"exampleFix":"// before\nTimerJobEntity timer = TimerJobEntity.createAndInsertJob(job);\nschedule(timer); // duedate null -> throws\n\n// after\nTimerJobEntity timer = TimerJobEntity.createAndInsertJob(job);\ntimer.setDuedate(new Date(System.currentTimeMillis() + Duration.ofMinutes(5).toMillis()));\nschedule(timer);","handlingStrategy":"validation","validationCode":"if (timer.getDuedate() == null) {\n    timer.setDuedate(computeDuedateFromDefinition(timer));\n}\nschedule(timer);","typeGuard":"function isSchedulable(timer) {\n  return timer.getDuedate() instanceof Date;\n}","tryCatchPattern":"try {\n    jobEntityManager.schedule(timer);\n} catch (ActivitiIllegalArgumentException e) {\n    log.error(\"Timer {} has no duedate; check its time expression/variables\", timer.getId());\n}","preventionTips":["Always set duedate before scheduling programmatically","Ensure timer event expressions reference defined, non-null process variables","Validate timer definitions (timeDate/timeDuration/timeCycle) at deployment"],"tags":["timer","job","null-argument"],"backgroundTag":"missing-required-argument","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"}