{"record":{"id":"ccc48abdf4bbdc66","repo":"flowable/flowable-engine","slug":"deadletterjobids-are-null","errorCode":null,"errorMessage":"deadLetterJobIds are null","messagePattern":"deadLetterJobIds are null","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/cmd/BulkMoveDeadLetterJobsCmd.java","lineNumber":50,"sourceCode":"public class BulkMoveDeadLetterJobsCmd implements Command<Void> {\n\n    private static final Logger LOGGER = LoggerFactory.getLogger(BulkMoveDeadLetterJobsCmd.class);\n\n    protected JobServiceConfiguration jobServiceConfiguration;\n\n    protected Collection<String> deadLetterJobIds;\n    protected int retries;\n\n    public BulkMoveDeadLetterJobsCmd(Collection<String> deadLetterJobIds, int retries, JobServiceConfiguration jobServiceConfiguration) {\n        this.deadLetterJobIds = deadLetterJobIds;\n        this.retries = retries;\n        this.jobServiceConfiguration = jobServiceConfiguration;\n    }\n\n    @Override\n    public Void execute(CommandContext commandContext) {\n        if (deadLetterJobIds == null) {\n            throw new FlowableIllegalArgumentException(\"deadLetterJobIds are null\");\n        }\n\n        DeadLetterJobQueryImpl query = new DeadLetterJobQueryImpl(commandContext, jobServiceConfiguration);\n        query.jobIds(deadLetterJobIds);\n        List<Job> deadLetterJobs = jobServiceConfiguration.getDeadLetterJobEntityManager().findJobsByQueryCriteria(query);\n\n        for (Job job : deadLetterJobs) {\n            if (HistoryJobEntity.HISTORY_JOB_TYPE.equals(job.getJobType())) {\n                if (LOGGER.isDebugEnabled()) {\n                    LOGGER.debug(\"Moving deadletter job to history job table {}\", job.getId());\n                }\n                jobServiceConfiguration.getJobManager().moveDeadLetterJobToHistoryJob((DeadLetterJobEntity) job, retries);\n            } else {\n                if (LOGGER.isDebugEnabled()) {\n                    LOGGER.debug(\"Moving deadletter job to executable job table {}\", job.getId());\n                }\n                jobServiceConfiguration.getJobManager().moveDeadLetterJobToExecutableJob((DeadLetterJobEntity) job, retries);\n            }","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/cmd/BulkMoveDeadLetterJobsCmd.java#L32-L68","documentation":"Thrown by BulkMoveDeadLetterJobsCmd.execute() when the deadLetterJobIds collection is null. Flowable distinguishes null (invalid input) from empty (valid but no-op) collections; a null collection cannot back the jobIds query filter, so the command rejects it immediately.","triggerScenarios":"managementService.moveDeadLetterJobs(...) (bulk move) called with a null id list; building the id list from a stream/collection that was null; passing an optional collection without a null check.","commonSituations":"Collecting failed job ids from a query that returned null instead of a list; API callers omitting the ids field which binds to null; refactor merging two id sources where one is null.","solutions":["Pass a non-null collection, even an empty one, to the bulk move API","Guard the call site: if (ids != null) managementService.moveDeadLetterJobs(ids)","Null-coalesce at the call: moveDeadLetterJobs(ids == null ? Collections.emptyList() : ids)"],"exampleFix":"// before\njobService.moveDeadLetterJobs(failedJobIds); // may be null\n// after\nif (failedJobIds != null) {\n    jobService.moveDeadLetterJobs(failedJobIds);\n}","handlingStrategy":"validation","validationCode":"if (deadLetterJobIds == null) {\n    throw new IllegalArgumentException(\"deadLetterJobIds must be non-null (use an empty list for no-op)\");\n}","typeGuard":"boolean hasIds(List<String> ids) { return ids != null; }","tryCatchPattern":"try {\n    jobService.moveDeadLetterJobs(deadLetterJobIds);\n} catch (FlowableIllegalArgumentException e) {\n    LOGGER.error(\"Bulk move rejected: {}\", e.getMessage());\n}","preventionTips":["Initialize id collections to empty lists, never null","Null-check collections returned from queries before passing them on","Wrap the bulk move call in a validation helper"],"tags":["validation","flowable","dead-letter-job"],"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"}