{"record":{"id":"1350ab0572d66caa","repo":"flowable/flowable-engine","slug":"deadletterjobids-are-null-1350ab","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/BulkMoveDeadLetterJobsToHistoryJobsCmd.java","lineNumber":49,"sourceCode":"public class BulkMoveDeadLetterJobsToHistoryJobsCmd implements Command<Void> {\n\n    private static final Logger LOGGER = LoggerFactory.getLogger(BulkMoveDeadLetterJobsToHistoryJobsCmd.class);\n\n    protected JobServiceConfiguration jobServiceConfiguration;\n\n    protected Collection<String> deadLetterJobIds;\n    protected int retries;\n\n    public BulkMoveDeadLetterJobsToHistoryJobsCmd(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        DeadLetterJobQueryImpl query = new DeadLetterJobQueryImpl(commandContext, jobServiceConfiguration);\n        query.jobIds(deadLetterJobIds);\n        List<Job> deadLetterJobs = jobServiceConfiguration.getDeadLetterJobEntityManager().findJobsByQueryCriteria(query);\n        for (Job job : deadLetterJobs) {\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        }\n        return null;\n    }\n\n}\n","sourceCodeStart":31,"sourceCodeEnd":64,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/cmd/BulkMoveDeadLetterJobsToHistoryJobsCmd.java#L31-L64","documentation":"Thrown by BulkMoveDeadLetterJobsToHistoryJobsCmd.execute() when deadLetterJobIds is null. This command bulk-moves dead letter jobs to history (removing runtime dead letter rows); it rejects a null id collection before running the query, treating it as a programming error rather than an empty batch.","triggerScenarios":"Calling the history-move bulk API (moveDeadLetterJobsToHistoryJobs-style management call) with a null list; deserialization producing a null ids array; a variable initialized as null and only assigned conditionally.","commonSituations":"Nightly cleanup job whose id list source returned null; API/REST layer not setting the ids property; migration code assuming a default empty list.","solutions":["Initialize the id list to an empty collection so the call is a safe no-op","Null-check before invoking the bulk history move","Fix the producer that should return an empty list instead of null"],"exampleFix":"// before\nList<String> ids = fetchDeadLetterJobIds(); // may return null\njobService.moveDeadLetterJobsToHistoryJobs(ids);\n// after\nList<String> ids = fetchDeadLetterJobIds();\njobService.moveDeadLetterJobsToHistoryJobs(ids != null ? ids : Collections.emptyList());","handlingStrategy":"validation","validationCode":"List<String> ids = fetched != null ? fetched : Collections.emptyList();","typeGuard":"boolean isUsableIdList(List<String> ids) { return ids != null; }","tryCatchPattern":"try {\n    jobService.moveDeadLetterJobsToHistoryJobs(deadLetterJobIds);\n} catch (FlowableIllegalArgumentException e) {\n    LOGGER.error(\"Bulk history move rejected: {}\", e.getMessage());\n}","preventionTips":["Make id-list producers return empty collections instead of null","Default-null the ids field in DTOs before calling the service","Add a startup assertion/test covering the null-list path"],"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"}