flowable/flowable-engine · error · FlowableIllegalArgumentException

callbackIds is null or empty

Error message

callbackIds is null or empty

What it means

FlowableIllegalArgumentException thrown by CaseInstanceQueryImpl.caseInstanceCallbackIds(Set<String>) when the callbackIds argument is null or an empty set. Flowable query builders validate required filter parameters eagerly so invalid queries fail at construction time instead of producing broken SQL. Pass a non-empty set of callback ids.

Solutions

  1. Pass a non-empty Set of callback ids to caseInstanceCallbackIds.
  2. If no filter is wanted, skip the call entirely instead of passing null/empty.
  3. Guard caller-side: only invoke the method when ids != null && !ids.isEmpty().
  4. Check upstream data extraction (e.g. from request body) that yields an empty set.

Example fix

// before
query.caseInstanceCallbackIds(request.getCallbackIds()); // may be null/empty
// after
Set<String> ids = request.getCallbackIds();
if (ids != null && !ids.isEmpty()) {
    query.caseInstanceCallbackIds(ids);
}
Defensive patterns

Strategy: validation

Validate before calling

Set<String> ids = ...;
if (ids == null || ids.isEmpty()) { throw new IllegalArgumentException("callbackIds must be non-empty"); }
query.caseInstanceCallbackIds(ids);

Type guard

boolean hasCallbackIds(Set<String> s) { return s != null && !s.isEmpty(); }

Try / catch

try { query.caseInstanceCallbackIds(ids); } catch (FlowableIllegalArgumentException e) { log.warn("invalid callbackIds filter: {}", e.getMessage()); }

Prevention

When it happens

Trigger: Calling caseInstanceCallbackIds(null) or caseInstanceCallbackIds(new HashSet<>()) / Set.of() (empty) on a CaseInstanceQuery, including inside an or() block.

Common situations: Building the query dynamically from user input where the callback-id list is absent or was never populated; deserialization producing an empty set; refactors that renamed a variable leaving it null.

Related errors


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

Appendix: source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/CaseInstanceQueryImpl.java:648

    }

    @Override
    public CaseInstanceQuery caseInstanceCallbackId(String callbackId) {
        if (callbackId == null) {
            throw new FlowableIllegalArgumentException("callbackId is null");
        }
        if (inOrStatement) {
            this.currentOrQueryObject.callbackId = callbackId;
        } else {
            this.callbackId = callbackId;
        }
        return this;
    }

    @Override
    public CaseInstanceQuery caseInstanceCallbackIds(Set<String> callbackIds) {
        if (callbackIds == null || callbackIds.isEmpty()) {
            throw new FlowableIllegalArgumentException("callbackIds is null or empty");
        }
        if (inOrStatement) {
            this.currentOrQueryObject.callbackIds = callbackIds;
        } else {
            this.callbackIds = callbackIds;
        }
        return this;
    }

    @Override
    public CaseInstanceQuery caseInstanceCallbackType(String callbackType) {
        if (callbackType == null) {
            throw new FlowableIllegalArgumentException("callbackType is null");
        }
        if (inOrStatement) {
            this.currentOrQueryObject.callbackType = callbackType;
        } else {
            this.callbackType = callbackType;

View on GitHub (pinned to d6d39ce1c6)