flowable/flowable-engine · error · FlowableException

Null planItemInstance passed

Error message

Null planItemInstance passed

What it means

CmmnDelegateHelper.getCmmnModel(DelegatePlanItemInstance) is a static helper for custom delegates to access the CMMN model of the current case definition. It explicitly rejects a null DelegatePlanItemInstance with a FlowableException because there is no case definition id to resolve the model from.

Source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/delegate/CmmnDelegateHelper.java:47

import org.flowable.cmmn.model.PlanItem;
import org.flowable.cmmn.model.PlanItemDefinition;
import org.flowable.cmmn.model.TaskWithFieldExtensions;
import org.flowable.common.engine.api.FlowableException;
import org.flowable.common.engine.api.delegate.Expression;
import org.flowable.common.engine.impl.el.ExpressionManager;
import org.flowable.common.engine.impl.el.FixedValue;

/**
 * @author Joram Barrez
 */
public class CmmnDelegateHelper {

    /**
     * Returns the {@link CmmnModel} matching the case definition cmmn model for the case definition of the passed {@link DelegatePlanItemInstance}.
     */
    public static CmmnModel getCmmnModel(DelegatePlanItemInstance  planItemInstance) {
        if (planItemInstance == null) {
            throw new  FlowableException("Null planItemInstance passed");
        }
        return CaseDefinitionUtil.getCmmnModel(planItemInstance.getCaseDefinitionId());
    }

    /**
     * Returns the current {@link CmmnElement} where the {@link DelegatePlanItemInstance} is currently at.
     */
    public static CmmnElement getCmmnElement(DelegatePlanItemInstance planItemInstance) {
        CmmnModel cmmnModel =  getCmmnModel(planItemInstance);
        CaseElement caseElement = null;
        if (planItemInstance.getPlanItem() != null) {
            caseElement = cmmnModel.getPrimaryCase().getAllCaseElements().get(planItemInstance.getPlanItem().getId());
            if (caseElement == null) {
                throw new FlowableException("Could not find a CmmnElement for id " + planItemInstance.getPlanItem().getId());
            }
        }
        return caseElement;
    }

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Ensure the delegate method receives and passes the actual DelegatePlanItemInstance from the engine context.
  2. Null-check the plan item instance before calling the helper and handle the null case explicitly.
  3. In tests, build a real/stubbed DelegatePlanItemInstance with a valid caseDefinitionId instead of passing null.
  4. If you need the model outside a plan item context, use CaseDefinitionUtil/CmmnRepositoryService with a case definition id directly.

Example fix

// before
CmmnModel model = CmmnDelegateHelper.getCmmnModel(null);
// after
if (planItemInstance != null) {
  CmmnModel model = CmmnDelegateHelper.getCmmnModel(planItemInstance);
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (planItemInstance == null || planItemInstance.getCaseDefinitionId() == null) {
    throw new IllegalArgumentException("planItemInstance with caseDefinitionId required");
}

Type guard

boolean usableForModelLookup(DelegatePlanItemInstance p) {
    return p != null && p.getCaseDefinitionId() != null;
}

Try / catch

try {
    CmmnModel model = CmmnDelegateHelper.getCmmnModel(planItemInstance);
} catch (org.flowable.common.engine.api.FlowableException e) {
    if ("Null planItemInstance passed".equals(e.getMessage())) { log.warn("No plan item context available"); return null; }
    throw e;
}

Prevention

When it happens

Trigger: Custom code (delegate, listener, JavaDelegate) calls CmmnDelegateHelper.getCmmnModel(null), e.g. when the plan item instance reference was never assigned, comes from a mocked test, or was derived from a context that returned null.

Common situations: Unit-testing delegates with hand-built/mocked plan item instances left null; calling the helper outside a plan-item execution context (e.g. from a case-level listener); refactoring dropped the argument.

Related errors


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