{"record":{"id":"fb89e21b0dea38c0","repo":"flowable/flowable-engine","slug":"null-job-provided","errorCode":null,"errorMessage":"Null job provided","messagePattern":"Null job provided","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/asyncexecutor/DefaultJobManager.java","lineNumber":265,"sourceCode":"        } else {\n            throw new FlowableIllegalArgumentException(\"Cannot move the job to deadletter: the job is not a timer, async job or external worker job\");\n        }\n\n        return deadLetterJob;\n    }\n\n    protected void sendMoveToDeadletterEvent(JobInfo job) {\n        FlowableEventDispatcher eventDispatcher = jobServiceConfiguration.getEventDispatcher();\n        if (eventDispatcher != null && eventDispatcher.isEnabled()) {\n            eventDispatcher.dispatchEvent(FlowableJobEventBuilder.createEntityEvent(\n                FlowableEngineEventType.JOB_MOVED_TO_DEADLETTER, job), jobServiceConfiguration.getEngineName());\n        }\n    }\n\n    @Override\n    public Job moveDeadLetterJobToExecutableJob(DeadLetterJobEntity deadLetterJobEntity, int retries) {\n        if (deadLetterJobEntity == null) {\n            throw new FlowableIllegalArgumentException(\"Null job provided\");\n        }\n\n        if (HistoryJobEntity.HISTORY_JOB_TYPE.equals(deadLetterJobEntity.getJobType())) {\n            throw new FlowableIllegalArgumentException(\"Cannot move a history job to an executable job\");\n        }\n\n        if (Job.JOB_TYPE_EXTERNAL_WORKER.equals(deadLetterJobEntity.getJobType())) {\n            ExternalWorkerJobEntity externalWorkerJob = createExternalWorkerJobFromOtherJob(deadLetterJobEntity);\n            externalWorkerJob.setRetries(retries);\n            boolean insertSuccessful = jobServiceConfiguration.getExternalWorkerJobEntityManager().insertExternalWorkerJobEntity(externalWorkerJob);\n            if (insertSuccessful) {\n                jobServiceConfiguration.getDeadLetterJobEntityManager().delete(deadLetterJobEntity);\n                return externalWorkerJob;\n            }\n        } else {\n            JobEntity executableJob = createExecutableJobFromOtherJob(deadLetterJobEntity);\n            executableJob.setRetries(retries);\n            boolean insertSuccessful = jobServiceConfiguration.getJobEntityManager().insertJobEntity(executableJob);","sourceCodeStart":247,"sourceCodeEnd":283,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/asyncexecutor/DefaultJobManager.java#L247-L283","documentation":"moveDeadLetterJobToExecutableJob resurrects a DeadLetterJobEntity back to the executable job table with a reset retry count. A null dead-letter job cannot be moved, so the method throws FlowableIllegalArgumentException as a fail-fast precondition.","triggerScenarios":"Passing null to JobManager.moveDeadLetterJobToExecutableJob(deadLetterJobEntity, retries), typically forwarding the result of a dead-letter-job lookup that found nothing.","commonSituations":"Admin/retry consoles that look up a dead-letter job by id and call the move without checking for a missing record; jobs concurrently deleted by another node.","solutions":["Fetch and null-check the DeadLetterJobEntity (e.g. via managementService) before calling the move","Return a clear 'job not found' message to the user when the lookup returns null","Catch FlowableIllegalArgumentException and map it to a not-found handling path"],"exampleFix":"// before\njobManager.moveDeadLetterJobToExecutableJob(deadLetterJob, 3);\n// after\nif (deadLetterJob != null) {\n    jobManager.moveDeadLetterJobToExecutableJob(deadLetterJob, 3);\n}","handlingStrategy":"validation","validationCode":"if (deadLetterJobEntity == null) { throw new JobNotFoundException(\"Dead letter job not found\"); }","typeGuard":"boolean canMove(DeadLetterJobEntity d) { return d != null && d.getId() != null; }","tryCatchPattern":"try { jobManager.moveDeadLetterJobToExecutableJob(job, retries); } catch (FlowableIllegalArgumentException e) { throw new JobNotFoundException(\"Dead letter job missing: \" + e.getMessage()); }","preventionTips":["Verify the dead-letter job exists before moving","Handle concurrent deletion of dead-letter jobs","Null-check admin-console lookups"],"tags":["flowable","job-scheduling","null-check","deadletter"],"backgroundTag":"null-argument","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"}