flowable/flowable-engine · error · ActivitiIllegalArgumentException

job is null

Error message

job is null

What it means

Thrown by LockExclusiveJobCmd.execute() when the job field is null. This command locks an exclusive job in the job table and requires a concrete JobEntity, so a null job is rejected immediately with ActivitiIllegalArgumentException.

Solutions

  1. Ensure the job entity is loaded (fetch JobEntity by id) before locking
  2. Check custom executor code for a path that passes a null job
  3. Re-query the job; if it is gone the work item was already handled and locking is unnecessary

Example fix

// before
commandExecutor.execute(new LockExclusiveJobCmd(job)); // job may be null
// after
if (job != null) {
    commandExecutor.execute(new LockExclusiveJobCmd(job));
}
Defensive patterns

Strategy: validation

Validate before calling

if (job == null) throw new IllegalStateException("cannot lock a null job");

Try / catch

try { commandExecutor.execute(new LockExclusiveJobCmd(job)); } catch (ActivitiIllegalArgumentException e) { log.error("lock called with null job"); }

Prevention

When it happens

Trigger: Calling managementService (or internal command executor) to run LockExclusiveJobCmd with a null job; internal executor paths passing a job that failed to load; constructing the command with no job and executing it.

Common situations: Custom async-executor or job-acquisition code feeding null into the command; a job deleted by another thread between acquisition and locking; misconfigured command factory.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/8309e889cbbb5afe. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/LockExclusiveJobCmd.java:44

 * @author Tijs Rademakers
 */
public class LockExclusiveJobCmd implements Command<Object>, Serializable {

    private static final long serialVersionUID = 1L;

    private static final Logger LOGGER = LoggerFactory.getLogger(LockExclusiveJobCmd.class);

    protected JobEntity job;

    public LockExclusiveJobCmd(JobEntity job) {
        this.job = job;
    }

    @Override
    public Object execute(CommandContext commandContext) {

        if (job == null) {
            throw new ActivitiIllegalArgumentException("job is null");
        }

        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Executing lock exclusive job {} {}", job.getId(), job.getExecutionId());
        }

        if (job.isExclusive()) {
            if (job.getExecutionId() != null) {
                ExecutionEntity execution = commandContext.getExecutionEntityManager().findExecutionById(job.getExecutionId());
                if (execution != null) {
                    commandContext.getExecutionEntityManager().updateProcessInstanceLockTime(execution.getProcessInstanceId());
                }
            }
        }

        return null;
    }
}

View on GitHub (pinned to d6d39ce1c6)