flowable/flowable-engine · error · FlowableIllegalArgumentException

The job id is mandatory, but

Error message

The job id is mandatory, but '${jobId}' has been provided.

What it means

The SetJobRetriesCmd constructor validates that jobId is non-null and non-empty before storing it, throwing FlowableIllegalArgumentException when the id is null or zero-length. Setting the retry count of a job is meaningless without identifying the job, so the command fails fast at construction time.

Solutions

  1. Check jobId is non-null and not blank before calling setJobRetries.
  2. Filter out null/empty ids in batch retry operations.
  3. Fix the producer of the empty/null job id (form, query, message).

Example fix

// before
managementService.setJobRetries(jobId, 3);
// after
if (jobId != null && !jobId.trim().isEmpty()) {
    managementService.setJobRetries(jobId, 3);
}
Defensive patterns

Strategy: validation

Validate before calling

if (jobId == null || jobId.trim().isEmpty()) throw new IllegalArgumentException("jobId is mandatory");

Type guard

boolean validJobId = jobId != null && jobId.length() > 0;

Try / catch

try { managementService.setJobRetries(jobId, retries); } catch (FlowableIllegalArgumentException e) { log.error("setJobRetries rejected: {}", e.getMessage()); }

Prevention

When it happens

Trigger: Calling ManagementService.setJobRetries(jobId, retries) (or new SetJobRetriesCmd(...)) with jobId == null or "".

Common situations: Empty string from a blank UI/config field; null id from a map lookup or optional job reference; retry scripts that iterate jobs with missing ids.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

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

import org.flowable.job.service.JobServiceConfiguration;
import org.flowable.job.service.event.impl.FlowableJobEventBuilder;
import org.flowable.job.service.impl.persistence.entity.JobEntity;

/**
 * @author Falko Menge
 */
public class SetJobRetriesCmd implements Command<Void>, Serializable {

    private static final long serialVersionUID = 1L;
    
    protected JobServiceConfiguration jobServiceConfiguration;

    protected final String jobId;
    protected final int retries;

    public SetJobRetriesCmd(String jobId, int retries, JobServiceConfiguration jobServiceConfiguration) {
        if (jobId == null || jobId.length() < 1) {
            throw new FlowableIllegalArgumentException("The job id is mandatory, but '" + jobId + "' has been provided.");
        }
        if (retries < 0) {
            throw new FlowableIllegalArgumentException("The number of job retries must be a non-negative Integer, but '" + retries + "' has been provided.");
        }
        this.jobId = jobId;
        this.retries = retries;
        this.jobServiceConfiguration = jobServiceConfiguration;
    }

    @Override
    public Void execute(CommandContext commandContext) {
        JobEntity job = jobServiceConfiguration.getJobEntityManager().findById(jobId);
        if (job != null) {

            job.setRetries(retries);

            FlowableEventDispatcher eventDispatcher = jobServiceConfiguration.getEventDispatcher();
            if (eventDispatcher != null && eventDispatcher.isEnabled()) {

View on GitHub (pinned to d6d39ce1c6)