{"record":{"id":"f0bcb0d70eb6ab00","repo":"flowable/flowable-engine","slug":"could-not-find-job-for-id-jobid","errorCode":null,"errorMessage":"Could not find job for id ${jobId}","messagePattern":"Could not find job for id (.+?)","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/cmd/UnacquireExternalWorkerJobCmd.java","lineNumber":50,"sourceCode":"        this.workerId = workerId;\n        this.jobServiceConfiguration = jobServiceConfiguration;\n    }\n\n    @Override\n    public Void execute(CommandContext commandContext) {\n        if (StringUtils.isEmpty(jobId)) {\n            throw new FlowableIllegalArgumentException(\"job id must not be empty\");\n        }\n\n        if (StringUtils.isEmpty(workerId)) {\n            throw new FlowableIllegalArgumentException(\"worker id must not be empty\");\n        }\n\n        ExternalWorkerJobEntityManager externalWorkerJobEntityManager = jobServiceConfiguration.getExternalWorkerJobEntityManager();\n\n        ExternalWorkerJobEntity jobEntity = externalWorkerJobEntityManager.findById(jobId);\n        if (jobEntity == null) {\n            throw new FlowableException(\"Could not find job for id \" + jobId);\n        }\n        \n        if (!jobEntity.getLockOwner().equals(workerId)) {\n            throw new FlowableException(jobEntity + \" is locked with a different worker id\");\n        }\n\n        jobEntity.setLockExpirationTime(null);\n        jobEntity.setLockOwner(null);\n        externalWorkerJobEntityManager.update(jobEntity);\n        if (jobEntity.isExclusive()) {\n            new UnlockExclusiveJobCmd(jobEntity, jobServiceConfiguration).execute(commandContext);\n        }\n        \n        return null;\n    }\n}\n","sourceCodeStart":32,"sourceCodeEnd":67,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/cmd/UnacquireExternalWorkerJobCmd.java#L32-L67","documentation":"UnacquireExternalWorkerJobCmd.execute throws this FlowableException (not a typed not-found exception) when findById on the external worker job entity manager returns null for the given jobId. The job to unacquire no longer exists in the runtime tables, so the release operation cannot be performed.","triggerScenarios":"Calling unacquireExternalWorkerJob with an id of a job that was completed, deleted, or never an external worker job; the job lock expired and another worker completed/removed it; stale id retained after the async executor processed the job; wrong datasource/environment.","commonSituations":"Two workers racing on the same expired lock; job ids cached across restarts; pointing the client at a different database (dev vs prod); job moved out of the external worker table after acquisition.","solutions":["Treat this as a benign race in the handler: catch FlowableException and log/skip if the job is gone","Refresh the job id from a fresh ExternalWorkerJobQuery before unacquiring","Reduce lock expiration races by handling jobs well within the lock duration","Verify the datasource points at the same database the job was acquired from"],"exampleFix":"// before\nexternalWorkerJobService.unacquireExternalWorkerJob(jobId, workerId); // throws if job vanished\n// after\ntry {\n    externalWorkerJobService.unacquireExternalWorkerJob(jobId, workerId);\n} catch (FlowableException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"Could not find job\")) {\n        logger.info(\"Job {} already gone; skipping unacquire\", jobId);\n    } else {\n        throw e;\n    }\n}","handlingStrategy":"try-catch","validationCode":"ExternalWorkerJobEntity job = externalWorkerJobService.createExternalWorkerJobQuery().jobId(jobId).singleResult();\nif (job == null) { /* job gone, skip */ }","typeGuard":null,"tryCatchPattern":"try {\n    externalWorkerJobService.unacquireExternalWorkerJob(jobId, workerId);\n} catch (FlowableException e) {\n    logger.info(\"Job {} disappeared before unacquire (already completed?)\", jobId);\n}","preventionTips":["Design handlers to treat missing jobs as benign races","Keep processing within the lock duration to avoid re-acquisition","Avoid caching job ids across process restarts","Verify datasource consistency between acquire and unacquire environments"],"tags":["not-found","flowable","external-worker","race-condition"],"backgroundTag":"entity-not-found","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}