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

  1. Move the two-argument call outside the or()/endOr() block (combine with AND semantics)
  2. Inside the OR block, use the single-argument processInstanceBusinessKey(businessKey) plus a separate processDefinitionKey() criterion only per supported OR rules
  3. Restructure the search so OR-criteria use only allowed methods (e.g. businessKey, executionId, tenantId)
  4. 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

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


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)