flowable/flowable-engine · error · FlowableException

the query is already in an or statement

Error message

the query is already in an or statement

What it means

EventSubscriptionQuery.or() opens an OR block in the fluent query. Flowable throws FlowableException (not an argument error) if or() is invoked while the query is already inside an OR statement, because nested OR groups are unsupported by this query implementation. This is an API-state rule, not a data problem.

Source

Thrown at modules/flowable-eventsubscription-service/src/main/java/org/flowable/eventsubscription/service/impl/EventSubscriptionQueryImpl.java:474

        }

        return this;
    }

    @Override
    public EventSubscriptionQueryImpl withoutConfiguration() {
        if (inOrStatement) {
            this.currentOrQueryObject.withoutConfiguration = true;
        } else {
            this.withoutConfiguration = true;
        }
        return this;
    }

    @Override
    public EventSubscriptionQuery or() {
        if (inOrStatement) {
            throw new FlowableException("the query is already in an or statement");
        }

        inOrStatement = true;
        currentOrQueryObject = new EventSubscriptionQueryImpl();
        orQueryObjects.add(currentOrQueryObject);
        return this;
    }

    @Override
    public EventSubscriptionQuery endOr() {
        if (!inOrStatement) {
            throw new FlowableException("endOr() can only be called after calling or()");
        }

        inOrStatement = false;
        currentOrQueryObject = null;
        return this;
    }

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Call or() once, add all OR-joined predicates, then call endOr() before opening another block
  2. Guard the or() call with a boolean flag tracking whether the OR block is open
  3. Restructure the loop to add criteria inside a single or()...endOr() span

Example fix

// before
for (Filter f : filters) {
    query.or().eventSubscriptionType(f.getType());
}

// after
query.or();
for (Filter f : filters) {
    query.eventSubscriptionType(f.getType());
}
query.endOr();
Defensive patterns

Strategy: try-catch

Validate before calling

if (query instanceof EventSubscriptionQueryImpl && ((EventSubscriptionQueryImpl) query).inOrStatement) {
    throw new IllegalStateException("or() called while already in OR statement");
}

Try / catch

try {
    query.or();
} catch (FlowableException e) {
    log.error("Nested or() not supported: {}", e.getMessage());
    throw e;
}

Prevention

When it happens

Trigger: Calling query.or() twice without an intervening endOr(), e.g. building filters in a loop that calls or() per condition, or duplicating query-building code paths that each open an OR block.

Common situations: Dynamic filter builders where the same or() call is executed for each incoming filter criterion; copy-pasted query assembly in two branches both calling or().

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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