flowable/flowable-engine · error · FlowableIllegalArgumentException

EntryCriterionId is null

Error message

EntryCriterionId is null

What it means

HistoricPlanItemInstanceQueryImpl.planItemInstanceEntryCriterionId() rejects a null entryCriterionId with FlowableIllegalArgumentException. Filtering historic plan items by entry criterion requires the criterion's concrete element id.

Source

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

            this.referenceId = referenceId;
        }
        return this;
    }

    @Override
    public HistoricPlanItemInstanceQuery planItemInstanceReferenceType(String referenceType) {
        if (inOrStatement) {
            this.currentOrQueryObject.referenceType = referenceType;
        } else {
            this.referenceType = referenceType;
        }
        return this;
    }

    @Override
    public HistoricPlanItemInstanceQuery planItemInstanceEntryCriterionId(String entryCriterionId) {
        if (entryCriterionId == null) {
            throw new FlowableIllegalArgumentException("EntryCriterionId is null");
        }
        if (inOrStatement) {
            this.currentOrQueryObject.entryCriterionId = entryCriterionId;
        } else {
            this.entryCriterionId = entryCriterionId;
        }
        return this;
    }

    @Override
    public HistoricPlanItemInstanceQuery planItemInstanceExitCriterionId(String exitCriterionId) {
        if (exitCriterionId == null) {
            throw new FlowableIllegalArgumentException("ExitCriterionId is null");
        }
        if (inOrStatement) {
            this.currentOrQueryObject.exitCriterionId = exitCriterionId;
        } else {
            this.exitCriterionId = exitCriterionId;

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Null-check the id before calling and skip the filter when null
  2. Pass the correct entry criterion element id from the CMMN model
  3. Verify the criterion id exists in the deployed case definition before querying
  4. Use planItemInstanceExitCriterionId instead if you meant the exit criterion

Example fix

// before
query.planItemInstanceEntryCriterionId(criterionId).list();
// after
if (criterionId != null) {
    query.planItemInstanceEntryCriterionId(criterionId);
}
List<HistoricPlanItemInstance> results = query.list();
Defensive patterns

Strategy: validation

Validate before calling

if (entryCriterionId != null) {
    query.planItemInstanceEntryCriterionId(entryCriterionId);
}

Type guard

boolean hasCriterion(String id) { return id != null && !id.isEmpty(); }

Try / catch

try {
    query.planItemInstanceEntryCriterionId(criterionId);
} catch (FlowableIllegalArgumentException e) {
    if (!e.getMessage().contains("EntryCriterionId is null")) throw e;
    // proceed without the criterion filter
}

Prevention

When it happens

Trigger: Calling planItemInstanceEntryCriterionId(null), often from a plan-item/model lookup (e.g. criteria map lookup) that returned null.

Common situations: Resolving entry criterion ids from CMMN model XML where the referenced criterion does not exist; variables extracted from case model parsing failing to resolve.

Related errors


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