{"record":{"id":"a884d687daa6acbc","repo":"flowable/flowable-engine","slug":"timer-job-not-found-for-id","errorCode":null,"errorMessage":"Timer job not found for id ","messagePattern":"Timer job not found for id ","errorType":"exception","errorClass":"FlowableObjectNotFoundException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/RescheduleTimerJobCmd.java","lineNumber":80,"sourceCode":"            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        \n        if (planItemInstance == null) {\n            planItemInstance = CommandContextUtil.getPlanItemInstanceEntityManager(commandContext).findById(timerJob.getSubScopeId());\n            if (planItemInstance == null) {\n                throw new FlowableException(\"Plan item instance not found for id \" + timerJob.getSubScopeId());\n            }\n        }\n        \n        Date timerDueDate = null;\n        boolean isRepeating = false;\n        if (newDueDate != null) {\n            timerDueDate = newDueDate;\n            \n        } else if (newDateValue != null) {\n            BusinessCalendarManager businessCalendarManager = CommandContextUtil.getCmmnEngineConfiguration(commandContext).getBusinessCalendarManager();\n            if (isDurationString(newDateValue)) {\n                timerDueDate = businessCalendarManager.getBusinessCalendar(DueDateBusinessCalendar.NAME).resolveDuedate(newDateValue);","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/RescheduleTimerJobCmd.java#L62-L98","documentation":"RescheduleTimerJobCmd looks up a CMMN timer job by id before rescheduling it. If TimerJobService.findTimerJobById returns null, the command throws FlowableObjectNotFoundException, meaning no timer job with that id exists (possibly already executed, deleted, or belonging to another engine).","triggerScenarios":"Calling CmmnTaskService/planItem runtime API to change due date or repeat interval of a timer job whose id is stale, already fired, or was removed by case completion.","commonSituations":"Rescheduling a job after the plan item instance already completed and the job was deleted; using an id string from a different engine/datasource; race between job execution (acquire/delete) and a user-driven reschedule request.","solutions":["Verify the timer job id is still present via TimerJobQuery / job runtime tables before rescheduling","Re-fetch the plan item instance and re-query its current jobs instead of caching the job id","Check for race conditions with the async job acquire/execute threads deleting the job","Confirm you are connected to the same database/schema where the job was created"],"exampleFix":"// before\nruntimeService.setTimerJobDueDate(staleJobId, newDueDate);\n// after\nTimerJob job = timerJobService.createTimerJobQuery().timerJobId(staleJobId).singleResult();\nif (job != null) {\n    runtimeService.setTimerJobDueDate(staleJobId, newDueDate);\n}","handlingStrategy":"validation","validationCode":"TimerJob job = timerJobService.createTimerJobQuery().timerJobId(jobId).singleResult();\nif (job == null) throw new IllegalStateException(\"Timer job gone: \" + jobId);","typeGuard":null,"tryCatchPattern":"try { runtimeService.setTimerJobDueDate(jobId, due); } catch (FlowableObjectNotFoundException e) { log.warn(\"Timer job vanished, skipping reschedule: {}\", jobId); }","preventionTips":["Never cache timer job ids across request lifecycles","Re-query jobs at reschedule time","Watch for job-acquire threads racing user actions"],"tags":["cmmn","timer-job","not-found"],"backgroundTag":"record-not-found","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}