flowable/flowable-engine · error · FlowableIllegalArgumentException
jobId is null
Error message
jobId is null
What it means
ExecuteAsyncRunnableJobCmd validates both dependencies: if its injected jobEntityManager is null it throws "jobEntityManager is null", and if jobId is null it throws FlowableIllegalArgumentException("jobId is null"). Unlike ExecuteAsyncJobCmd it does not fall back to the configuration, so both fields must be supplied explicitly.
Source
Thrown at modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/cmd/ExecuteAsyncRunnableJobCmd.java:64
public ExecuteAsyncRunnableJobCmd(String jobId, JobInfoEntityManager<? extends JobInfoEntity> jobEntityManager,
JobServiceConfiguration jobServiceConfiguration, boolean unlock) {
this.jobId = jobId;
this.jobEntityManager = jobEntityManager;
this.jobServiceConfiguration = jobServiceConfiguration;
this.unlock = unlock;
}
@Override
public Object execute(CommandContext commandContext) {
if (jobEntityManager == null) {
throw new FlowableIllegalArgumentException("jobEntityManager is null");
}
if (jobId == null) {
throw new FlowableIllegalArgumentException("jobId is null");
}
// We need to refetch the job, as it could have been deleted by another concurrent job
// For example: an embedded subprocess with a couple of async tasks and a timer on the boundary of the subprocess
// when the timer fires, all executions and thus also the jobs inside of the embedded subprocess are destroyed.
// However, the async task jobs could already have been fetched and put in the queue.... while in reality they have been deleted.
// A refetch is thus needed here to be sure that it exists for this transaction.
JobInfoEntity job = jobEntityManager.findById(jobId);
if (job == null) {
LOGGER.debug("Job does not exist anymore and will not be executed. It has most likely been deleted "
+ "as part of another concurrent part of the process instance.");
return null;
}
if (LOGGER.isDebugEnabled()) {
if (job instanceof JobEntity) {
LOGGER.debug("Executing async job {}", job.getId());View on GitHub (pinned to d6d39ce1c6)
Solutions
- Pass a non-null JobEntityManager obtained from JobServiceConfiguration when constructing the command.
- Ensure the job id is set on the entity before dispatching the runnable.
- Prefer ExecuteAsyncJobCmd, which resolves the entity manager from the configuration as a fallback.
- Add null checks in the code that instantiates this command so failures surface at your boundary.
Example fix
// before new ExecuteAsyncRunnableJobCmd(null, jobId); // jobEntityManager is null // after new ExecuteAsyncRunnableJobCmd(jobServiceConfiguration.getJobEntityManager(), jobId);
Defensive patterns
Strategy: validation
Validate before calling
if (jobEntityManager == null) { throw new IllegalArgumentException("jobEntityManager required"); }
if (jobId == null) { throw new IllegalArgumentException("jobId required"); } Try / catch
try { commandExecutor.execute(cmd); } catch (FlowableIllegalArgumentException e) { LOGGER.error("Bad ExecuteAsyncRunnableJobCmd input: {}", e.getMessage()); } Prevention
- Always source the JobEntityManager from JobServiceConfiguration, never hand-roll nulls.
- Prefer ExecuteAsyncJobCmd which falls back to the configuration's entity manager.
- Set the entity id before dispatching any runnable.
When it happens
Trigger: Executing new ExecuteAsyncRunnableJobCmd(null, ...) or new ExecuteAsyncRunnableJobCmd(em, null) via the command executor; async runnable dispatch paths that lost the entity manager reference.
Common situations: Hand-wiring the command in tests or custom code without providing the entity manager; job runnable factories passing a job whose id was never assigned; misconfiguration where a custom JobEntityManager bean is missing.
Related errors
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/646767d28628a2d6.
Report an issue: GitHub.