flowable/flowable-engine · error · FlowableIllegalArgumentException

Business key is null

Error message

Business key is null

What it means

ExecutionQueryImpl.processInstanceBusinessKey(String) throws FlowableIllegalArgumentException when the business key is null. The business key filter maps to a WHERE condition on ACT_RU_EXECUTION.BUSINESS_KEY_, so a null value cannot be translated into a meaningful predicate. Flowable validates eagerly so the error surfaces at query build time, not at list()/singleResult().

Solutions

  1. Validate the business key is non-null/non-blank before building the query
  2. For optional keys, only add the filter when present (conditional query building)
  3. Sanitize/trim empty strings to null consciously and branch on it
  4. Catch FlowableIllegalArgumentException to convert it into a 400-style response

Example fix

// before
ExecutionQuery query = runtimeService.createExecutionQuery().processInstanceBusinessKey(businessKey);
// after
ExecutionQuery query = runtimeService.createExecutionQuery();
if (businessKey != null && !businessKey.isBlank()) {
    query.processInstanceBusinessKey(businessKey);
}
Defensive patterns

Strategy: validation

Validate before calling

if (businessKey == null || businessKey.isBlank()) {
    throw new IllegalArgumentException("businessKey must not be null or blank");
}

Type guard

boolean hasBusinessKey(String key) {
    return key != null && !key.isBlank();
}

Try / catch

try {
    Execution exec = runtimeService.createExecutionQuery().processInstanceBusinessKey(key).singleResult();
} catch (FlowableIllegalArgumentException e) {
    throw new BadRequestException("businessKey is required", e);
}

Prevention

When it happens

Trigger: Calling processInstanceBusinessKey(null), usually when the business key originates from external input, a form field, or an upstream variable that was never set.

Common situations: REST endpoints with optional business-key params passed straight into the query; legacy data lacking business keys; refactor where a default constant was removed.

Related errors


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

Appendix: source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/ExecutionQueryImpl.java:342

    }

    @Override
    public ExecutionQueryImpl rootProcessInstanceId(String rootProcessInstanceId) {
        if (rootProcessInstanceId == null) {
            throw new FlowableIllegalArgumentException("Root process instance id is null");
        }
        if (inOrStatement) {
            this.currentOrQueryObject.rootProcessInstanceId = rootProcessInstanceId;
        } else {
            this.rootProcessInstanceId = rootProcessInstanceId;
        }
        return this;
    }

    @Override
    public ExecutionQuery processInstanceBusinessKey(String businessKey) {
        if (businessKey == null) {
            throw new FlowableIllegalArgumentException("Business key is null");
        }
        if (inOrStatement) {
            this.currentOrQueryObject.businessKey = businessKey;
        } else {
            this.businessKey = businessKey;
        }
        return this;
    }

    @Override
    public ExecutionQuery processInstanceBusinessKey(String processInstanceBusinessKey, boolean includeChildExecutions) {
        if (!includeChildExecutions) {
            return processInstanceBusinessKey(processInstanceBusinessKey);
        } else {
            if (processInstanceBusinessKey == null) {
                throw new FlowableIllegalArgumentException("Business key is null");
            }
            

View on GitHub (pinned to d6d39ce1c6)