{"record":{"id":"57c8c77370f78af4","repo":"flowable/flowable-engine","slug":"cannot-delete-job-when-the-job-is-being-execute","errorCode":null,"errorMessage":"Cannot delete ${job} when the job is being executed. Try again later.","messagePattern":"Cannot delete (.+?) when the job is being executed\\. Try again later\\.","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"warning","filePath":"modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/cmd/DeleteTimerJobCmd.java","lineNumber":83,"sourceCode":"\n    protected TimerJobEntity getJobToDelete(CommandContext commandContext) {\n        if (timerJobId == null) {\n            throw new FlowableIllegalArgumentException(\"jobId is null\");\n        }\n        if (LOGGER.isDebugEnabled()) {\n            LOGGER.debug(\"Deleting job {}\", timerJobId);\n        }\n\n        TimerJobEntity job = jobServiceConfiguration.getTimerJobEntityManager().findById(timerJobId);\n        if (job == null) {\n            throw new FlowableObjectNotFoundException(\"No timer job found with id '\" + timerJobId + \"'\", Job.class);\n        }\n\n        // We need to check if the job was locked, ie acquired by the job acquisition thread\n        // This happens if the job was already acquired, but not yet executed.\n        // In that case, we can't allow to delete the job.\n        if (job.getLockOwner() != null) {\n            throw new FlowableException(\"Cannot delete \" + job + \" when the job is being executed. Try again later.\");\n        }\n        return job;\n    }\n\n}\n","sourceCodeStart":65,"sourceCodeEnd":89,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/cmd/DeleteTimerJobCmd.java#L65-L89","documentation":"After finding the timer job, DeleteTimerJobCmd checks job.getLockOwner(); a non-null lock owner means the async executor acquisition thread already locked the job for execution, so deleting it would race with a running job. The command throws a plain FlowableException telling the caller to retry later.","triggerScenarios":"managementService.deleteTimerJob(id) called while the async executor has acquired but not yet executed the timer job (lock owner column populated).","commonSituations":"Admin/UI code deleting timers at the same moment the job executor fires them; high-load systems where the acquisition thread grabs timers between a user query and the delete; canceling a process instance manually via job deletion instead of letting engine cascade handle it.","solutions":["Retry the delete after a short delay until the lock owner is cleared (job executed or lock released).","Cancel the owning execution/process instance instead of deleting the timer directly, so the engine cleans up safely.","Catch FlowableException and implement exponential backoff for this transient condition.","Temporarily suspend the job executor during bulk timer cleanup operations."],"exampleFix":"// before\nmanagementService.deleteTimerJob(timerJobId); // FlowableException if locked\n// after\nTimerJobInfo job = managementService.createTimerJobQuery().timerJobId(timerJobId).singleResult();\nif (job != null) {\n    managementService.deleteTimerJob(timerJobId); // retry with backoff on FlowableException\n}","handlingStrategy":"retry","validationCode":"TimerJobInfo j = managementService.createTimerJobQuery().timerJobId(id).singleResult();\nboolean locked = j != null; // lock owner not exposed; rely on retry for FlowableException","typeGuard":null,"tryCatchPattern":"try { managementService.deleteTimerJob(id); } catch (FlowableException e) { scheduler.schedule(this::deleteWithBackoff, 2, SECONDS); }","preventionTips":["Implement exponential backoff retries around timer job deletion.","Prefer canceling the owning execution/process instance over deleting locked jobs manually.","Suspend the job executor during bulk timer maintenance windows."],"tags":["flowable","job-service","concurrency","job-lock"],"backgroundTag":"invalid-state-transition","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"}