flowable/flowable-engine · error · FlowableIllegalArgumentException

Cannot use executionId together with excludeLocalVariables

Error message

Cannot use executionId together with excludeLocalVariables

What it means

Flowable's VariableInstanceQuery.executionId() rejects being combined with excludeLocalVariables because execution-scoped variable lookups only make sense for local or non-local scopes, and the API treats this combination as contradictory. The check in executionId(String) throws FlowableIllegalArgumentException before any state is set. The query is never executed; this is an argument-validation failure at query-build time.

Solutions

  1. Remove the excludeLocalVariables() call from the query
  2. If you need both filtering semantics, split into two queries: one with executionId and one with excludeLocalVariables for a different scope
  3. Use includeNonLocalVariables or no exclusion flag and post-filter results instead

Example fix

// before
variableInstanceQuery.excludeLocalVariables().executionId(executionId);
// after
variableInstanceQuery.executionId(executionId);
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

boolean isCompatibleQuery(VariableInstanceQuery q) { return q != null; } // no runtime narrowing available; guard is done at call site

Try / catch

try {
    query.executionId(executionId);
} catch (FlowableIllegalArgumentException e) {
    if (e.getMessage().contains("excludeLocalVariables")) {
        query = createBaseQuery(); // rebuild without exclusion flag
        query.executionId(executionId);
    } else { throw e; }
}

Prevention

When it happens

Trigger: Calling new VariableInstanceQueryImpl(...).excludeLocalVariables().executionId("some-exec-id") (or executionId before excludeLocalVariables) on the VariableInstanceQuery API.

Common situations: Developers copy a query template that filters out local variables and then add an executionId filter, or refactor code where excludeLocalVariables was set for a task-based query and reused it for an execution-scoped query.

Related errors


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

Appendix: source

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

        return this;
    }

    @Override
    public VariableInstanceQueryImpl processInstanceId(String processInstanceId) {
        if (processInstanceId == null) {
            throw new FlowableIllegalArgumentException("processInstanceId is null");
        }
        this.processInstanceId = processInstanceId;
        return this;
    }

    @Override
    public VariableInstanceQueryImpl executionId(String executionId) {
        if (executionId == null) {
            throw new FlowableIllegalArgumentException("Execution id is null");
        }
        if (excludeLocalVariables) {
            throw new FlowableIllegalArgumentException("Cannot use executionId together with excludeLocalVariables");
        }
        this.executionId = executionId;
        return this;
    }

    @Override
    public VariableInstanceQueryImpl executionIds(Set<String> executionIds) {
        if (executionIds == null) {
            throw new FlowableIllegalArgumentException("executionIds is null");
        }
        if (executionIds.isEmpty()) {
            throw new FlowableIllegalArgumentException("Set of executionIds is empty");
        }
        if (excludeLocalVariables) {
            throw new FlowableIllegalArgumentException("Cannot use executionIds together with excludeLocalVariables");
        }
        this.executionIds = executionIds;
        return this;

View on GitHub (pinned to d6d39ce1c6)