flowable/flowable-engine · error · FlowableIllegalArgumentException

Cannot use subScopeId together with excludeLocalVariables

Error message

Cannot use subScopeId together with excludeLocalVariables

What it means

Flowable throws FlowableIllegalArgumentException when subScopeId(...) is called on a VariableInstanceQuery that already has excludeLocalVariables enabled. The two options are mutually exclusive: excludeLocalVariables changes the query semantics in a way that cannot be combined with sub-scope filtering, so the builder refuses the combination at call time.

Solutions

  1. Remove one of the two conflicting options: drop the subScopeId call or drop excludeLocalVariables()
  2. Choose the scoping strategy explicitly — if you need sub-scope filtering, do not exclude local variables
  3. Build two alternative queries depending on whether a subScopeId is present

Example fix

// before
query.excludeLocalVariables();
query.subScopeId(subScopeId); // throws
// after
query.subScopeId(subScopeId); // pick one strategy
// or, without subScopeId:
query.excludeLocalVariables();
Defensive patterns

Strategy: validation

Validate before calling

if (subScopeId != null && excludeLocal) {
    throw new IllegalArgumentException("subScopeId cannot be combined with excludeLocalVariables");
}
query.subScopeId(subScopeId);

Try / catch

try {
    query.excludeLocalVariables().subScopeId(subScopeId);
} catch (FlowableIllegalArgumentException e) {
    if (e.getMessage().contains("subScopeId together with excludeLocalVariables")) {
        // rebuild the query with only one of the two options
        query = variableInstanceQueryService.createVariableInstanceQuery().subScopeId(subScopeId);
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling query.excludeLocalVariables().subScopeId("someSubScopeId") in either order (subScopeId after excludeLocalVariables triggers this message); shared query-builder code that always enables exclusion then optionally adds a subScopeId.

Common situations: Refactors that added excludeLocalVariables to a base query while other call sites still pass a subScopeId; copy-pasted query setup that mixes variable-scoping strategies.

Related errors


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

Appendix: source

Thrown at modules/flowable-variable-service/src/main/java/org/flowable/variable/service/impl/VariableInstanceQueryImpl.java:248

    @Override
    public VariableInstanceQuery variableNameLike(String variableNameLike) {
        if (variableNameLike == null) {
            throw new FlowableIllegalArgumentException("variableNameLike is null");
        }
        this.variableNameLike = variableNameLike;
        return this;
    }
    
    @Override
    public VariableInstanceQuery scopeId(String scopeId) {
        this.scopeId = scopeId;
        return this;
    }
    
    @Override
    public VariableInstanceQuery subScopeId(String subScopeId) {
        if (excludeLocalVariables) {
            throw new FlowableIllegalArgumentException("Cannot use subScopeId together with excludeLocalVariables");
        }
        this.subScopeId = subScopeId;
        return this;
    }
    
    @Override
    public VariableInstanceQuery scopeType(String scopeType) {
        this.scopeType = scopeType;
        return this;
    }

    @Override
    public VariableInstanceQuery excludeLocalVariables() {
        if (taskId != null) {
            throw new FlowableIllegalArgumentException("Cannot use taskId together with excludeLocalVariables");
        }
        if (taskIds != null) {
            throw new FlowableIllegalArgumentException("Cannot use taskIds together with excludeLocalVariables");

View on GitHub (pinned to d6d39ce1c6)