flowable/flowable-engine · error · ActivitiIllegalArgumentException
This method is not supported in an OR statement
Error message
This method is not supported in an OR statement
What it means
Within an OR statement (query.or()...endOr()), only a subset of filter methods is supported. The two-argument processInstanceBusinessKey(businessKey, processDefinitionKey) throws ActivitiIllegalArgumentException('This method is not supported in an OR statement') because setting two fields at once breaks the single-criteria model of the OR block.
Solutions
- Move the two-argument call outside the or()/endOr() block (combine with AND semantics)
- Inside the OR block, use the single-argument processInstanceBusinessKey(businessKey) plus a separate processDefinitionKey() criterion only per supported OR rules
- Restructure the search so OR-criteria use only allowed methods (e.g. businessKey, executionId, tenantId)
- Catch ActivitiIllegalArgumentException during query construction in tests to catch unsupported combinations early
Example fix
// before
query.or()
.processInstanceBusinessKey(bk, defKey) // not allowed in OR
.processInstanceTenantId(tenant)
.endOr();
// after
query.processDefinitionKey(defKey); // AND-level
query.or()
.processInstanceBusinessKey(bk) // OR-safe overload
.processInstanceTenantId(tenant)
.endOr(); Defensive patterns
Strategy: try-catch
Validate before calling
boolean inOr = false; // track via query state or code review // only call two-arg overload when NOT inside or()/endOr(): query.processInstanceBusinessKey(businessKey, processDefinitionKey); // AND scope only
Type guard
boolean orSafeFilter(java.util.function.Function<ProcessInstanceQuery,ProcessInstanceQuery> f) { return f != null; } // apply OR-safe methods only inside or() blocks Try / catch
try {
query.or().processInstanceBusinessKey(bk, dk).endOr();
} catch (ActivitiIllegalArgumentException e) {
if (e.getMessage().contains("not supported in an OR statement")) {
// restructure: apply two-arg filter outside OR, single-arg inside
}
throw e;
} Prevention
- Restrict OR blocks to the documented supported methods (businessKey single-arg, executionId, tenantId, etc.)
- Centralize OR-query building in one helper reviewed against the supported list
- Write a test that builds every OR query combination the app uses
- Use the single-argument overload inside OR and put definition-key narrowing at AND level
When it happens
Trigger: Calling the two-argument overload between or() and endOr(), e.g. code that generically applies 'key + definition' filters and got refactored into an OR query for multi-criteria search.
Common situations: Advanced search forms that combine criteria with OR logic; copy-pasted query code moved into an or() block without checking the supported-methods list.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- activity tenant id is null
- Business key is null
- Deployment id is null
- deploymentCategory is null
- deploymentCategoryExclude is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/4eb49a718aa4f1cd.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/ProcessInstanceQueryImpl.java:145
public ProcessInstanceQuery processInstanceBusinessKey(String businessKey) {
if (businessKey == null) {
throw new ActivitiIllegalArgumentException("Business key is null");
}
if (inOrStatement) {
this.currentOrQueryObject.businessKey = businessKey;
} else {
this.businessKey = businessKey;
}
return this;
}
@Override
public ProcessInstanceQuery processInstanceBusinessKey(String businessKey, String processDefinitionKey) {
if (businessKey == null) {
throw new ActivitiIllegalArgumentException("Business key is null");
}
if (inOrStatement) {
throw new ActivitiIllegalArgumentException("This method is not supported in an OR statement");
}
this.businessKey = businessKey;
this.processDefinitionKey = processDefinitionKey;
return this;
}
@Override
public ProcessInstanceQuery processInstanceTenantId(String tenantId) {
if (tenantId == null) {
throw new ActivitiIllegalArgumentException("process instance tenant id is null");
}
if (inOrStatement) {
this.currentOrQueryObject.tenantId = tenantId;
} else {
this.tenantId = tenantId;
}
return this;View on GitHub (pinned to d6d39ce1c6)