flowable/flowable-engine · error · FlowableObjectNotFoundException
No timer job found with id '
Error message
No timer job found with id '
What it means
DeleteTimerJobCmd looks up the timer job by id via TimerJobEntityManager.findById; when no row matches it throws FlowableObjectNotFoundException carrying Job.class as the type. It means the id is well-formed but no timer job with that id exists (or it no longer exists).
Source
Thrown at modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/cmd/DeleteTimerJobCmd.java:76
protected void sendCancelEvent(CommandContext commandContext, TimerJobEntity jobToDelete) {
FlowableEventDispatcher eventDispatcher = jobServiceConfiguration.getEventDispatcher();
if (eventDispatcher != null && eventDispatcher.isEnabled()) {
eventDispatcher.dispatchEvent(FlowableJobEventBuilder.createEntityEvent(FlowableEngineEventType.JOB_CANCELED, jobToDelete),
jobServiceConfiguration.getEngineName());
}
}
protected TimerJobEntity getJobToDelete(CommandContext commandContext) {
if (timerJobId == null) {
throw new FlowableIllegalArgumentException("jobId is null");
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Deleting job {}", timerJobId);
}
TimerJobEntity job = jobServiceConfiguration.getTimerJobEntityManager().findById(timerJobId);
if (job == null) {
throw new FlowableObjectNotFoundException("No timer job found with id '" + timerJobId + "'", Job.class);
}
// We need to check if the job was locked, ie acquired by the job acquisition thread
// This happens if the job was already acquired, but not yet executed.
// In that case, we can't allow to delete the job.
if (job.getLockOwner() != null) {
throw new FlowableException("Cannot delete " + job + " when the job is being executed. Try again later.");
}
return job;
}
}
View on GitHub (pinned to d6d39ce1c6)
Solutions
- Query the id first (managementService.createTimerJobQuery().timerJobId(id).singleResult()) and skip deletion when null.
- Catch FlowableObjectNotFoundException and treat the delete as already-done idempotently.
- Verify you are connected to the same database/engine the timer job was created in.
- Confirm you are not confusing job ids (ACT_RU_JOB) with timer job ids (ACT_RU_TIMER_JOB).
Example fix
// before
managementService.deleteTimerJob(timerJobId); // throws if already gone
// after
if (managementService.createTimerJobQuery().timerJobId(timerJobId).count() > 0) {
managementService.deleteTimerJob(timerJobId);
} Defensive patterns
Strategy: try-catch
Validate before calling
boolean exists = managementService.createTimerJobQuery().timerJobId(timerJobId).count() > 0;
Try / catch
try { managementService.deleteTimerJob(id); } catch (FlowableObjectNotFoundException e) { LOGGER.info("Timer job {} already gone", id); } Prevention
- Treat deletes as idempotent: catching not-found is usually correct for cleanup flows.
- Distinguish job vs timer-job vs dead-letter ids; each lives in its own table.
- Verify engine/database consistency in clustered deployments.
When it happens
Trigger: managementService.deleteTimerJob(id) with an id that was already deleted, a job id (not timer job id) from the ACT_RU_JOB table, an id from another engine/database, or a stale id after the timer fired and moved/disappeared.
Common situations: Deleting a timer that already fired (timer jobs move to job/dead-letter tables or vanish when the execution ends); clustered setups where the id exists on another node's database; tests reusing recorded ids across cleanups; passing a TimerJobEntity.getId() after the entity was deleted.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- jobId is null
- Could not find a resource with id '<resourceName>' in deploy
- Could not find an app deployment with id '<deploymentId>
- Could not find an app deployment with id '<deploymentId>
- Could not find a resource with name '<resourceName>' in depl
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/509e09fe5429b265.
Report an issue: GitHub.