{"record":{"id":"85b694d5074fc93f","repo":"flowable/flowable-engine","slug":"cannot-delete","errorCode":null,"errorMessage":"Cannot delete ","messagePattern":"Cannot delete ","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"warning","filePath":"modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/cmd/DeleteJobCmd.java","lineNumber":92,"sourceCode":"\n    protected JobEntity getJobToDelete(CommandContext commandContext) {\n        if (jobId == null) {\n            throw new FlowableIllegalArgumentException(\"jobId is null\");\n        }\n        if (LOGGER.isDebugEnabled()) {\n            LOGGER.debug(\"Deleting job {}\", jobId);\n        }\n\n        JobEntity job = jobServiceConfiguration.getJobEntityManager().findById(jobId);\n        if (job == null) {\n            throw new FlowableObjectNotFoundException(\"No job found with id '\" + jobId + \"'\", 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":74,"sourceCodeEnd":98,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/cmd/DeleteJobCmd.java#L74-L98","documentation":"After finding the job, DeleteJobCmd rejects deletion when the job is locked (lockOwner != null), i.e. the async executor's acquisition thread already picked it up and is executing it. Flowable throws a plain FlowableException(\"Cannot delete ... when the job is being executed. Try again later.\") to prevent deleting a job mid-execution.","triggerScenarios":"Calling managementService.deleteJob / DeleteJobCmd on a job that a job executor node has acquired (ACT_RU_JOB.LOCK_OWNER_ set, lock expiry not yet passed) — typical in clustered setups or immediately after an async step became runnable.","commonSituations":"Deleting an async continuation job while a service task is executing on another node; cleanup scripts running while the async executor is active; long-running jobs whose lock is repeatedly renewed so retries keep colliding.","solutions":["Retry after a short delay — the message explicitly says 'Try again later'; the lock expires if the executor dies or the job finishes.","Stop or scale down the async executor (or pause job acquisition) before bulk job deletion/maintenance.","Check job.getLockOwner()/lock expiration time before deleting, and skip locked jobs.","Shut down the engine gracefully (executor shutdown waits for running jobs) in tests/scripts that delete jobs."],"exampleFix":"// before\nmanagementService.deleteJob(jobId); // may be locked by the async executor\n// after\nJob job = managementService.createJobQuery().jobId(jobId).singleResult();\nif (job != null && job.getLockOwner() == null) {\n    managementService.deleteJob(jobId);\n}","handlingStrategy":"retry","validationCode":"Job job = managementService.createJobQuery().jobId(jobId).singleResult();\nif (job != null && job.getLockOwner() != null) {\n    LOGGER.info(\"Job {} is locked by {} — retry later\", jobId, job.getLockOwner());\n    return;\n}","typeGuard":null,"tryCatchPattern":"int attempts = 0;\nwhile (attempts < 3) {\n    try {\n        managementService.deleteJob(jobId);\n        break;\n    } catch (FlowableException e) {\n        if (!e.getMessage().contains(\"being executed\") || ++attempts == 3) throw e;\n        Thread.sleep(2000);\n    }\n}","preventionTips":["Check lockOwner before deleting jobs in clustered deployments.","Pause or shut down the async executor for maintenance deletions.","Back off and retry — locks expire when acquisition lapses."],"tags":["flowable","async-executor","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-14T05:17:10.506Z"}