flowable/flowable-engine · error · FlowableException
Process definition version must be a positive number
Error message
Process definition version must be a positive number
What it means
When no target process definition ID is set, build() validates that the optional migrateToProcessDefinitionVersion is a positive number. A negative version value is invalid because process definition versions start at 1, so build() throws this FlowableException.
Solutions
- Pass a positive version number (>= 1) to migrateToProcessDefinition(version, key)
- Use 1 or omit the version (migrateToProcessDefinitionKey) if you intend the first/latest version
- Validate or sanitize the version value before building the document
Example fix
// before builder.migrateToProcessDefinition(-1, "orderProcess"); // after int version = Math.max(1, configuredVersion); builder.migrateToProcessDefinition(version, "orderProcess");
Defensive patterns
Strategy: validation
Validate before calling
if (targetVersion != null && targetVersion < 1) {
throw new IllegalArgumentException("Process definition version must be >= 1");
} Type guard
boolean isValidVersion(Integer v) { return v == null || v >= 1; } Try / catch
try {
document = builder.build();
} catch (FlowableException e) {
if (e.getMessage().contains("must be a positive number")) {
builder.migrateToProcessDefinitionKey(key); // drop invalid version
document = builder.build();
} else { throw e; }
} Prevention
- Never use negative sentinels like -1 for 'latest version'
- Clamp or sanitize versions parsed from JSON/config
- Remember Flowable versions start at 1
When it happens
Trigger: Calling build() with migrateToProcessDefinitionId null and migrateToProcessDefinitionVersion set to a negative number, typically via migrateToProcessDefinition(version, key) or a JSON document with a negative version field.
Common situations: Passing a sentinel value like -1 for 'latest version'; parsing a version from config/JSON that was never sanitized; off-by-one or unsigned/signed confusion when computing versions.
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
- Cannot validate process migration, not enough information
- Must specify a process definition id to migrate
- Must specify a process instance id to migrate
- Must specify a process migration document to migrate
- Process definition key cannot be null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/ff6c189e0bbb66cb.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/migration/ProcessInstanceMigrationDocumentBuilderImpl.java:156
this.processInstanceVariables.put(variableName, variableValue);
return this;
}
@Override
public ProcessInstanceMigrationDocumentBuilder addProcessInstanceVariables(Map<String, Object> processInstanceVariables) {
this.processInstanceVariables.putAll(processInstanceVariables);
return this;
}
@Override
public ProcessInstanceMigrationDocument build() {
if (migrateToProcessDefinitionId == null) {
if (migrateToProcessDefinitionKey == null) {
throw new FlowableException("Process definition key cannot be null");
}
if (migrateToProcessDefinitionVersion != null && migrateToProcessDefinitionVersion < 0) {
throw new FlowableException("Process definition version must be a positive number");
}
}
ProcessInstanceMigrationDocumentImpl document = new ProcessInstanceMigrationDocumentImpl();
document.setProcessInstanceIdsToMigrate(processInstanceIdsToMigrate);
document.setMigrateToProcessDefinitionId(migrateToProcessDefinitionId);
document.setMigrateToProcessDefinition(migrateToProcessDefinitionKey, migrateToProcessDefinitionVersion, migrateToProcessDefinitionTenantId);
if (preUpgradeScript != null) {
document.setPreUpgradeScript(preUpgradeScript);
}
if (preUpgradeJavaDelegate != null) {
document.setPreUpgradeJavaDelegate(preUpgradeJavaDelegate);
}
if (preUpgradeJavaDelegateExpression != null) {
document.setPreUpgradeJavaDelegateExpression(preUpgradeJavaDelegateExpression);
}
if (postUpgradeScript != null) {
document.setPostUpgradeScript(postUpgradeScript);View on GitHub (pinned to d6d39ce1c6)