flowable/flowable-engine · error · ActivitiIllegalArgumentException
The number of job retries must be a non-negative Integer…
Error message
The number of job retries must be a non-negative Integer, but '" + retries + "' has been provided.
What it means
Constructor validation in flowable5 SetJobRetriesCmd: the retries value is negative; the engine requires a non-negative retry count, and the supplied value is echoed in the message.
Solutions
- Clamp the retry count before calling: Math.max(0, retries).
- Validate user/config input to ensure retries >= 0.
- Fix the computation that produces the negative value.
Example fix
// before managementService.setJobRetries(jobId, retries); // retries may be negative // after managementService.setJobRetries(jobId, Math.max(0, retries));
Defensive patterns
Strategy: validation
Validate before calling
if (retries < 0) throw new IllegalArgumentException("retries must be >= 0"); Try / catch
try { managementService.setJobRetries(jobId, retries); }
catch (ActivitiIllegalArgumentException e) { log.error("invalid retries value {}", retries); } Prevention
- Clamp counters with Math.max(0, retries)
- Validate user input at the boundary
- Use range-checked setters for retry configuration
When it happens
Trigger: new SetJobRetriesCmd(jobId, -1) or ManagementService.setJobRetries(jobId, negativeNumber).
Common situations: Retry count computed by subtracting attempts (going below zero), user input not validated, or off-by-one logic when decrementing retries.
Related errors
- The job id is mandatory, but '" + jobId + "' has been…
- An end date can only be provided when rescheduling a timer…
- At most one non-null value can be provided for timeDate…
- batchSize has to be larger than 0
- comment is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/ef370b2a7a98c769.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/SetJobRetriesCmd.java:43
import org.flowable.common.engine.impl.interceptor.EngineConfigurationConstants;
import org.flowable.job.api.Job;
/**
* @author Falko Menge
*/
public class SetJobRetriesCmd implements Command<Void>, Serializable {
private static final long serialVersionUID = 1L;
private final String jobId;
private final int retries;
public SetJobRetriesCmd(String jobId, int retries) {
if (jobId == null || jobId.length() < 1) {
throw new ActivitiIllegalArgumentException("The job id is mandatory, but '" + jobId + "' has been provided.");
}
if (retries < 0) {
throw new ActivitiIllegalArgumentException("The number of job retries must be a non-negative Integer, but '" + retries + "' has been provided.");
}
this.jobId = jobId;
this.retries = retries;
}
@Override
public Void execute(CommandContext commandContext) {
JobEntity job = commandContext
.getJobEntityManager()
.findJobById(jobId);
if (job != null) {
job.setRetries(retries);
if (commandContext.getEventDispatcher().isEnabled()) {
commandContext.getEventDispatcher().dispatchEvent(
ActivitiEventBuilder.createEntityEvent(FlowableEngineEventType.ENTITY_UPDATED, job),
EngineConfigurationConstants.KEY_PROCESS_ENGINE_CONFIG);
}View on GitHub (pinned to d6d39ce1c6)