flowable/flowable-engine · error · FlowableObjectNotFoundException

Timer job not found for id

Error message

Timer job not found for id 

What it means

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).

Source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/RescheduleTimerJobCmd.java:80

            List<Job> timerJobs = jobService.createTimerJobQuery().planItemInstanceId(eventListenerInstanceId).list();
            if (timerJobs == null || timerJobs.isEmpty()) {
                throw new FlowableException("No timer jobs found for plan item instance " + eventListenerInstanceId);
            }
            
            if (timerJobs.size() > 1) {
                throw new FlowableException("Multiple timer jobs found for plan item instance " + eventListenerInstanceId);
            }
            
            timerJobId = timerJobs.get(0).getId();
        
        } else {
            timerJobId = jobId;
        }
        
        TimerJobService timerJobService = CommandContextUtil.getTimerJobService(commandContext);
        TimerJobEntity timerJob = timerJobService.findTimerJobById(timerJobId);
        if (timerJob == null) {
            throw new FlowableObjectNotFoundException("Timer job not found for id " + timerJobId);
        }
        
        if (planItemInstance == null) {
            planItemInstance = CommandContextUtil.getPlanItemInstanceEntityManager(commandContext).findById(timerJob.getSubScopeId());
            if (planItemInstance == null) {
                throw new FlowableException("Plan item instance not found for id " + timerJob.getSubScopeId());
            }
        }
        
        Date timerDueDate = null;
        boolean isRepeating = false;
        if (newDueDate != null) {
            timerDueDate = newDueDate;
            
        } else if (newDateValue != null) {
            BusinessCalendarManager businessCalendarManager = CommandContextUtil.getCmmnEngineConfiguration(commandContext).getBusinessCalendarManager();
            if (isDurationString(newDateValue)) {
                timerDueDate = businessCalendarManager.getBusinessCalendar(DueDateBusinessCalendar.NAME).resolveDuedate(newDateValue);

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Verify the timer job id is still present via TimerJobQuery / job runtime tables before rescheduling
  2. Re-fetch the plan item instance and re-query its current jobs instead of caching the job id
  3. Check for race conditions with the async job acquire/execute threads deleting the job
  4. Confirm you are connected to the same database/schema where the job was created

Example fix

// before
runtimeService.setTimerJobDueDate(staleJobId, newDueDate);
// after
TimerJob job = timerJobService.createTimerJobQuery().timerJobId(staleJobId).singleResult();
if (job != null) {
    runtimeService.setTimerJobDueDate(staleJobId, newDueDate);
}
Defensive patterns

Strategy: validation

Validate before calling

TimerJob job = timerJobService.createTimerJobQuery().timerJobId(jobId).singleResult();
if (job == null) throw new IllegalStateException("Timer job gone: " + jobId);

Try / catch

try { runtimeService.setTimerJobDueDate(jobId, due); } catch (FlowableObjectNotFoundException e) { log.warn("Timer job vanished, skipping reschedule: {}", jobId); }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/a884d687daa6acbc. Report an issue: GitHub.