{"record":{"id":"3c4495ef5d4e89c9","repo":"flowable/flowable-engine","slug":"no-timer-jobs-found-for-plan-item-instance","errorCode":null,"errorMessage":"No timer jobs found for plan item instance ","messagePattern":"No timer jobs found for plan item instance ","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":64,"sourceCode":"        this.newDueDate = newDueDate;\n        this.newDateValue = newDateValue;\n    }\n\n    @Override\n    public Job execute(CommandContext commandContext) {\n        String timerJobId = null;\n        PlanItemInstance planItemInstance = null;\n        JobService jobService = CommandContextUtil.getJobService(commandContext);\n        \n        if (eventListenerInstanceId != null) {\n            planItemInstance = CommandContextUtil.getPlanItemInstanceEntityManager(commandContext).findById(eventListenerInstanceId);\n            if (planItemInstance == null) {\n                throw new FlowableObjectNotFoundException(\"No plan item instance found for id \" + eventListenerInstanceId);\n            }\n            \n            List<Job> timerJobs = jobService.createTimerJobQuery().planItemInstanceId(eventListenerInstanceId).list();\n            if (timerJobs == null || timerJobs.isEmpty()) {\n                throw new FlowableException(\"No timer jobs found for plan item instance \" + eventListenerInstanceId);\n            }\n            \n            if (timerJobs.size() > 1) {\n                throw new FlowableException(\"Multiple timer jobs found for plan item instance \" + eventListenerInstanceId);\n            }\n            \n            timerJobId = timerJobs.get(0).getId();\n        \n        } else {\n            timerJobId = jobId;\n        }\n        \n        TimerJobService timerJobService = CommandContextUtil.getTimerJobService(commandContext);\n        TimerJobEntity timerJob = timerJobService.findTimerJobById(timerJobId);\n        if (timerJob == null) {\n            throw new FlowableObjectNotFoundException(\"Timer job not found for id \" + timerJobId);\n        }\n        ","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/RescheduleTimerJobCmd.java#L46-L82","documentation":"RescheduleTimerJobCmd expects exactly one timer job for the given event listener plan item instance. When the timer job query returns no jobs it throws FlowableException 'No timer jobs found for plan item instance' because there is nothing to reschedule.","triggerScenarios":"Rescheduling an event listener instance that has no active timer job — e.g. the timer already fired, was cancelled, the listener never started a timer, or the job service query filters (tenant, category) exclude it.","commonSituations":"Calling reschedule twice (first call moves the job out of the timer job table); timer already expired and moved to the dead-letter/history tables; wrong tenant scoping hiding the job.","solutions":["Query the job first: jobService/createTimerJobQuery().planItemInstanceId(id).count() and only reschedule when count == 1","Check async executor state — a misconfigured async executor can leave no pending timer jobs","Confirm tenant/category filters match the job's","Catch FlowableException and treat already-fired timers as a benign case"],"exampleFix":"// before\nrescheduleTimer(eventListenerInstanceId, newDate);\n// after\nif (jobService.createTimerJobQuery().planItemInstanceId(eventListenerInstanceId).count() == 1) {\n    rescheduleTimer(eventListenerInstanceId, newDate);\n} else {\n    logger.warn(\"No (or multiple) timer jobs for {}, skipping reschedule\", eventListenerInstanceId);\n}","handlingStrategy":"validation","validationCode":"long n = jobService.createTimerJobQuery().planItemInstanceId(eventListenerInstanceId).count();\nif (n == 0) throw new IllegalStateException(\"No timer job to reschedule for \" + eventListenerInstanceId);","typeGuard":null,"tryCatchPattern":"try { reschedule(...); } catch (FlowableException e) { log.warn(\"Timer already fired or absent for {}\", eventListenerInstanceId); }","preventionTips":["Check job existence before rescheduling","Avoid double-reschedule calls","Verify async executor configuration and tenant filters"],"tags":["cmmn","timer-job","empty"],"backgroundTag":"empty-result-set","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"}