flowable/flowable-engine · error · ActivitiIllegalArgumentException

The process definition version must be positive, but '" +…

Error message

The process definition version must be positive, but '" + processDefinitionVersion + "' has been provided.

What it means

The constructor also requires the process definition version to be a positive integer (>= 1). Flowable5 versions start at 1, so zero or negative values can never match a deployed definition and are rejected with ActivitiIllegalArgumentException.

Solutions

  1. Ensure the target version is at least 1 before calling the command.
  2. Clamp or validate: if (version < 1) throw new IllegalArgumentException(...).
  3. Query deployed versions with ProcessDefinitionQuery to pick a valid version instead of computing one.
  4. Handle the downgrade-to-nothing case explicitly: if the instance is already at version 1, there is no previous version to migrate to.

Example fix

// before
int previous = currentVersion - 1; // can be 0
runtimeService.setProcessDefinitionVersion(processInstanceId, previous);
// after
if (currentVersion <= 1) {
    throw new IllegalStateException("Process instance " + processInstanceId + " is already at version 1");
}
runtimeService.setProcessDefinitionVersion(processInstanceId, currentVersion - 1);
Defensive patterns

Strategy: validation

Validate before calling

if (version == null || version < 1) {
    throw new IllegalArgumentException("version must be >= 1");
}

Type guard

boolean isPositive(Integer v) { return v != null && v >= 1; }

Try / catch

try {
    runtimeService.setProcessDefinitionVersion(pid, version);
} catch (org.activiti.engine.ActivitiIllegalArgumentException e) {
    // handle non-positive version
}

Prevention

When it happens

Trigger: new SetProcessDefinitionVersionCmd(processInstanceId, 0) or a negative integer, usually produced by off-by-one arithmetic (e.g. subtracting 1 from version 1) or an uninitialized counter.

Common situations: Code computing a 'previous version' as currentVersion - 1 when the instance already runs version 1; parsing versions from strings with a broken default of 0.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

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

 * @see http://forums.activiti.org/en/viewtopic.php?t=2918
 * @author Falko Menge
 */
public class SetProcessDefinitionVersionCmd implements Command<Void>, Serializable {

    private static final long serialVersionUID = 1L;

    private final String processInstanceId;
    private final Integer processDefinitionVersion;

    public SetProcessDefinitionVersionCmd(String processInstanceId, Integer processDefinitionVersion) {
        if (processInstanceId == null || processInstanceId.length() < 1) {
            throw new ActivitiIllegalArgumentException("The process instance id is mandatory, but '" + processInstanceId + "' has been provided.");
        }
        if (processDefinitionVersion == null) {
            throw new ActivitiIllegalArgumentException("The process definition version is mandatory, but 'null' has been provided.");
        }
        if (processDefinitionVersion < 1) {
            throw new ActivitiIllegalArgumentException("The process definition version must be positive, but '" + processDefinitionVersion + "' has been provided.");
        }
        this.processInstanceId = processInstanceId;
        this.processDefinitionVersion = processDefinitionVersion;
    }

    @Override
    public Void execute(CommandContext commandContext) {
        // check that the new process definition is just another version of the same
        // process definition that the process instance is using
        ExecutionEntityManager executionManager = commandContext.getExecutionEntityManager();
        ExecutionEntity processInstance = executionManager.findExecutionById(processInstanceId);
        if (processInstance == null) {
            throw new ActivitiObjectNotFoundException("No process instance found for id = '" + processInstanceId + "'.", ProcessInstance.class);
        } else if (!processInstance.isProcessInstanceType()) {
            throw new ActivitiIllegalArgumentException(
                    "A process instance id is required, but the provided id " +
                            "'" + processInstanceId + "' " +
                            "points to a child execution of process instance " +

View on GitHub (pinned to d6d39ce1c6)