flowable/flowable-engine · error · FlowableIllegalArgumentException

Case definition id is null

Error message

Case definition id is null

What it means

Flowable's HistoricCaseInstanceQueryImpl.caseDefinitionId() validates its argument before storing it. Passing null would produce a broken SQL query later, so the engine fails fast with FlowableIllegalArgumentException. The caller must supply a non-null case definition id string.

Solutions

  1. Ensure a non-null case definition id before calling caseDefinitionId, e.g. resolve it via the repository service
  2. If the filter is optional, skip calling caseDefinitionId instead of passing null
  3. Use caseDefinitionIds(Set) only with a non-null, non-empty set
  4. Catch FlowableIllegalArgumentException to return a 400-style validation error to the caller

Example fix

// before
query.caseDefinitionId(request.getCaseDefinitionId()); // NPE-ish: may be null
// after
String id = request.getCaseDefinitionId();
if (id != null) {
    query.caseDefinitionId(id);
}
Defensive patterns

Strategy: validation

Validate before calling

if (caseDefinitionId == null) { throw new IllegalArgumentException("caseDefinitionId is required"); }
query.caseDefinitionId(caseDefinitionId);

Type guard

boolean hasDefinitionId = (id instanceof String s) && !s.isEmpty();

Try / catch

try {
    query.caseDefinitionId(id);
} catch (FlowableIllegalArgumentException e) {
    throw new BadRequestException("Invalid case definition id filter", e);
}

Prevention

When it happens

Trigger: Calling historicCaseInstanceQuery.caseDefinitionId(null), or passing a variable/expression that resolves to null (e.g. an unset request parameter or lookup result).

Common situations: REST/UI layers forwarding optional query filters straight into the query builder; variables read from maps/JSON where the key is absent; refactors that changed how the id is obtained and now return null.

Related errors


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

Appendix: source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/history/HistoricCaseInstanceQueryImpl.java:158

    public HistoricCaseInstanceQueryImpl(CommandExecutor commandExecutor, CmmnEngineConfiguration cmmnEngineConfiguration) {
        super(commandExecutor, cmmnEngineConfiguration.getVariableServiceConfiguration());
        this.cmmnEngineConfiguration = cmmnEngineConfiguration;
    }

    @Override
    protected void ensureVariablesInitialized() {
        super.ensureVariablesInitialized();

        for (HistoricCaseInstanceQueryImpl orQueryObject : orQueryObjects) {
            orQueryObject.ensureVariablesInitialized();
        }
    }

    @Override
    public HistoricCaseInstanceQueryImpl caseDefinitionId(String caseDefinitionId) {
        if (caseDefinitionId == null) {
            throw new FlowableIllegalArgumentException("Case definition id is null");
        }
        if (inOrStatement) {
            this.currentOrQueryObject.caseDefinitionId = caseDefinitionId;
        } else {
            this.caseDefinitionId = caseDefinitionId;
        }
        return this;
    }

    @Override
    public HistoricCaseInstanceQuery caseDefinitionIds(Set<String> caseDefinitionIds) {
        if (caseDefinitionIds == null) {
            throw new FlowableIllegalArgumentException("Case definition ids is null");
        }
        if (inOrStatement) {
            this.currentOrQueryObject.caseDefinitionIds = caseDefinitionIds;
        } else {
            this.caseDefinitionIds = caseDefinitionIds;

View on GitHub (pinned to d6d39ce1c6)