{"record":{"id":"38f252ce9a94d899","repo":"flowable/flowable-engine","slug":"jobid-is-null-38f252","errorCode":null,"errorMessage":"jobId is null","messagePattern":"jobId is null","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/cmd/ExecuteAsyncJobCmd.java","lineNumber":64,"sourceCode":"    }\n    \n    public ExecuteAsyncJobCmd(String jobId, JobInfoEntityManager<? extends JobInfoEntity> jobEntityManager,\n            JobServiceConfiguration jobServiceConfiguration) {\n        \n        this.jobId = jobId;\n        this.jobEntityManager = jobEntityManager;\n        this.jobServiceConfiguration = jobServiceConfiguration;\n    }\n\n    @Override\n    public Object execute(CommandContext commandContext) {\n        \n        if (jobEntityManager == null) {\n            jobEntityManager = jobServiceConfiguration.getJobEntityManager(); // Backwards compatibility\n        }\n\n        if (jobId == null) {\n            throw new FlowableIllegalArgumentException(\"jobId is null\");\n        }\n\n        // We need to refetch the job, as it could have been deleted by another concurrent job\n        // For example: an embedded subprocess with a couple of async tasks and a timer on the boundary of the subprocess\n        // when the timer fires, all executions and thus also the jobs inside of the embedded subprocess are destroyed.\n        // However, the async task jobs could already have been fetched and put in the queue.... while in reality they have been deleted.\n        // A refetch is thus needed here to be sure that it exists for this transaction.\n\n        JobInfoEntity job = jobEntityManager.findById(jobId);\n        if (job == null) {\n            LOGGER.debug(\"Job does not exist anymore and will not be executed. It has most likely been deleted \"\n                    + \"as part of another concurrent part of the process instance.\");\n            return null;\n        }\n\n        if (LOGGER.isDebugEnabled()) {\n            LOGGER.debug(\"Executing async job {}\", job.getId());\n        }","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/cmd/ExecuteAsyncJobCmd.java#L46-L82","documentation":"ExecuteAsyncJobCmd throws FlowableIllegalArgumentException when its jobId constructor argument is null. Asynchronous job execution is keyed purely on the id, so a null id makes the command meaningless and is rejected up front.","triggerScenarios":"Executing new ExecuteAsyncJobCmd(null) via the command executor, or async executor continuation paths passing a null job id after a fetch/dequeue produced nothing.","commonSituations":"Custom job executor code enqueuing jobs where the id field was never set; wrapper APIs forwarding an optional id that the caller omitted; tests invoking the command directly without arguments.","solutions":["Ensure the id passed to the command/executor API is non-null before dispatching.","If the id comes from a queued message, guard the deserialization step so null ids are dropped with a log line.","Check custom executor wrappers that may pass a variable initialized to null.","Add an assert/early return in the code that builds the command."],"exampleFix":"// before\ncommandExecutor.execute(new ExecuteAsyncJobCmd(jobId)); // jobId may be null\n// after\nObjects.requireNonNull(jobId, \"jobId must not be null\");\ncommandExecutor.execute(new ExecuteAsyncJobCmd(jobId));","handlingStrategy":"validation","validationCode":"if (jobId == null || jobId.isBlank()) { throw new IllegalArgumentException(\"jobId required for ExecuteAsyncJobCmd\"); }","typeGuard":null,"tryCatchPattern":"try { commandExecutor.execute(new ExecuteAsyncJobCmd(jobId)); } catch (FlowableIllegalArgumentException e) { LOGGER.error(\"Rejected async job execution: {}\", e.getMessage()); }","preventionTips":["Validate ids at your service boundary before building commands.","Drop queued messages with null ids early and log them.","Use Objects.requireNonNull in wrappers around executor calls."],"tags":["flowable","job-service","null-argument","async-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-14T11:17:12.474Z"}