flowable/flowable-engine · error · FlowableIllegalArgumentException

JobId is null

Error message

JobId is null

What it means

ExecuteJobCmd throws FlowableIllegalArgumentException("JobId is null") when its jobId is null, then looks the job up and throws JobNotFoundException when absent. It is the command behind executing an existing async job by id.

Source

Thrown at modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/cmd/ExecuteJobCmd.java:50

public class ExecuteJobCmd implements Command<Object>, Serializable {

    private static final long serialVersionUID = 1L;

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

    protected String jobId;
    protected JobServiceConfiguration jobServiceConfiguration;

    public ExecuteJobCmd(String jobId, JobServiceConfiguration jobServiceConfiguration) {
        this.jobId = jobId;
        this.jobServiceConfiguration = jobServiceConfiguration;
    }

    @Override
    public Object execute(CommandContext commandContext) {

        if (jobId == null) {
            throw new FlowableIllegalArgumentException("JobId is null");
        }

        Job job = jobServiceConfiguration.getJobEntityManager().findById(jobId);

        if (job == null) {
            throw new JobNotFoundException(jobId);
        }

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

        InternalJobCompatibilityManager internalJobCompatibilityManager = jobServiceConfiguration.getInternalJobCompatibilityManager();
        if (internalJobCompatibilityManager != null && internalJobCompatibilityManager.isFlowable5Job(job)) {
            internalJobCompatibilityManager.executeV5Job(job);
            return null;
        }

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Pass a non-null job id obtained from managementService.createJobQuery() results.
  2. If resuming a failed job, take the id from the DeadLetterJobQuery result, not a stale variable.
  3. Guard wrapper methods with Objects.requireNonNull before invoking the API.
  4. Ensure your queue/dequeue code preserves the id field.

Example fix

// before
managementService.executeJob(jobId); // may be null
// after
Objects.requireNonNull(jobId, "jobId must not be null");
managementService.executeJob(jobId);
Defensive patterns

Strategy: validation

Validate before calling

if (jobId == null) { throw new IllegalArgumentException("jobId must not be null before executeJob"); }

Try / catch

try { managementService.executeJob(jobId); } catch (FlowableIllegalArgumentException e) { /* caller bug: null id */ } catch (JobNotFoundException e) { /* job already gone */ }

Prevention

When it happens

Trigger: managementService.executeJob(null) or executing new ExecuteJobCmd(null); executor paths that lost the id between dequeue and command creation.

Common situations: Custom code resuming dead-letter jobs where the id came back null from a query wrapper; calling executeJob on a variable not yet assigned; tests invoking the command directly.

Related errors


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