{"record":{"id":"0c9de6bbae2b4309","repo":"flowable/flowable-engine","slug":"null-planiteminstance-passed","errorCode":null,"errorMessage":"Null planItemInstance passed","messagePattern":"Null planItemInstance passed","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/delegate/CmmnDelegateHelper.java","lineNumber":47,"sourceCode":"import org.flowable.cmmn.model.PlanItem;\nimport org.flowable.cmmn.model.PlanItemDefinition;\nimport org.flowable.cmmn.model.TaskWithFieldExtensions;\nimport org.flowable.common.engine.api.FlowableException;\nimport org.flowable.common.engine.api.delegate.Expression;\nimport org.flowable.common.engine.impl.el.ExpressionManager;\nimport org.flowable.common.engine.impl.el.FixedValue;\n\n/**\n * @author Joram Barrez\n */\npublic class CmmnDelegateHelper {\n\n    /**\n     * Returns the {@link CmmnModel} matching the case definition cmmn model for the case definition of the passed {@link DelegatePlanItemInstance}.\n     */\n    public static CmmnModel getCmmnModel(DelegatePlanItemInstance  planItemInstance) {\n        if (planItemInstance == null) {\n            throw new  FlowableException(\"Null planItemInstance passed\");\n        }\n        return CaseDefinitionUtil.getCmmnModel(planItemInstance.getCaseDefinitionId());\n    }\n\n    /**\n     * Returns the current {@link CmmnElement} where the {@link DelegatePlanItemInstance} is currently at.\n     */\n    public static CmmnElement getCmmnElement(DelegatePlanItemInstance planItemInstance) {\n        CmmnModel cmmnModel =  getCmmnModel(planItemInstance);\n        CaseElement caseElement = null;\n        if (planItemInstance.getPlanItem() != null) {\n            caseElement = cmmnModel.getPrimaryCase().getAllCaseElements().get(planItemInstance.getPlanItem().getId());\n            if (caseElement == null) {\n                throw new FlowableException(\"Could not find a CmmnElement for id \" + planItemInstance.getPlanItem().getId());\n            }\n        }\n        return caseElement;\n    }","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/delegate/CmmnDelegateHelper.java#L29-L65","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ensure the delegate method receives and passes the actual DelegatePlanItemInstance from the engine context.","Null-check the plan item instance before calling the helper and handle the null case explicitly.","In tests, build a real/stubbed DelegatePlanItemInstance with a valid caseDefinitionId instead of passing null.","If you need the model outside a plan item context, use CaseDefinitionUtil/CmmnRepositoryService with a case definition id directly."],"exampleFix":"// before\nCmmnModel model = CmmnDelegateHelper.getCmmnModel(null);\n// after\nif (planItemInstance != null) {\n  CmmnModel model = CmmnDelegateHelper.getCmmnModel(planItemInstance);\n}","handlingStrategy":"type-guard","validationCode":"if (planItemInstance == null || planItemInstance.getCaseDefinitionId() == null) {\n    throw new IllegalArgumentException(\"planItemInstance with caseDefinitionId required\");\n}","typeGuard":"boolean usableForModelLookup(DelegatePlanItemInstance p) {\n    return p != null && p.getCaseDefinitionId() != null;\n}","tryCatchPattern":"try {\n    CmmnModel model = CmmnDelegateHelper.getCmmnModel(planItemInstance);\n} catch (org.flowable.common.engine.api.FlowableException e) {\n    if (\"Null planItemInstance passed\".equals(e.getMessage())) { log.warn(\"No plan item context available\"); return null; }\n    throw e;\n}","preventionTips":["Only call CmmnDelegateHelper from within an active plan item execution context.","Null-check arguments before calling static helper methods.","In tests, provide a stubbed DelegatePlanItemInstance instead of null."],"tags":["java","cmmn","null-check","flowable"],"backgroundTag":"null-argument","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}