{"record":{"id":"431af28f70526bc1","repo":"flowable/flowable-engine","slug":"could-not-execute-decision-no-externalref-defined","errorCode":null,"errorMessage":"Could not execute decision: no externalRef defined for ${planItemInstanceEntity}","messagePattern":"Could not execute decision: no externalRef defined for (.+?)","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/behavior/impl/DecisionTaskActivityBehavior.java","lineNumber":79,"sourceCode":"        DmnDecisionService dmnRuleService = CommandContextUtil.getDmnRuleService(commandContext);\r\n        if (dmnRuleService == null) {\r\n            throw new FlowableException(\"Could not execute decision instance: no dmn service found. For \" + planItemInstanceEntity);\r\n        }\r\n\r\n        String externalRef = null;\r\n        if (decisionTask != null && decisionTask.getDecision() != null &&\r\n                StringUtils.isNotEmpty(decisionTask.getDecision().getExternalRef())) {\r\n            \r\n            externalRef = decisionTask.getDecision().getExternalRef();\r\n            \r\n        } else if (decisionRefExpression != null) {\r\n            Object externalRefValue = decisionRefExpression.getValue(planItemInstanceEntity);\r\n            if (externalRefValue != null) {\r\n                externalRef = externalRefValue.toString();\r\n            }\r\n            \r\n            if (StringUtils.isEmpty(externalRef)) {\r\n                throw new FlowableException(\"Could not execute decision: no externalRef defined for \" + planItemInstanceEntity);\r\n            }\r\n        }\r\n\r\n        CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);\r\n\r\n        ExecuteDecisionBuilder executeDecisionBuilder = dmnRuleService.createExecuteDecisionBuilder().\r\n            decisionKey(externalRef).\r\n            instanceId(planItemInstanceEntity.getCaseInstanceId()).\r\n            executionId(planItemInstanceEntity.getId()).\r\n            activityId(decisionTask.getId()).\r\n            scopeType(ScopeTypes.CMMN).\r\n            variables(planItemInstanceEntity.getVariables()).\r\n            tenantId(planItemInstanceEntity.getTenantId());\r\n\r\n        String fallBackToDefaultTenantValue = getFieldString(STRING_DECISION_TABLE_FALLBACK_TO_DEFAULT_TENANT);\r\n        if (Boolean.parseBoolean(fallBackToDefaultTenantValue)) {\r\n            executeDecisionBuilder.fallbackToDefaultTenant();\r\n        }\r","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/behavior/impl/DecisionTaskActivityBehavior.java#L61-L97","documentation":"When a decision task references its decision via an external reference, the behavior evaluates the decision ref expression and requires a non-empty externalRef string. If the expression is defined but evaluates to null/empty, the engine cannot identify which DMN decision to execute and throws this FlowableException.","triggerScenarios":"A decision task with an externalRef (decision ref) expression whose evaluation on the plan item instance yields null or the empty string at plan item activation.","commonSituations":"Case variables not set before the decision task activates; a typo in the expression variable name; the decision's externalRef attribute left empty in the case model while the expression path was expected to supply it.","solutions":["Set the variable(s) referenced by the decision ref expression before the plan item reaches ACTIVE state (e.g. via case start form, data object, or a preceding service task).","Fix the expression syntax in the case model so it resolves to the decision key, e.g. ${decisionKey} where decisionKey is a case variable.","Set a literal externalRef on the decision task element in the CMMN XML if the key is static.","Guard the flow: use a condition/sentry so the decision task only activates once the referenced variable is populated."],"exampleFix":"// before: activates with missing variable\ncaseRuntimeService.setVariable(caseInstanceId, \"decisonKey\", \"myDecision\"); // typo -> expression yields null\n// after\ncaseRuntimeService.setVariable(caseInstanceId, \"decisionKey\", \"myDecision\");","handlingStrategy":"validation","validationCode":"String externalRef = (String) caseInstance.getCaseVariables().get(\"decisionKey\");\nif (externalRef == null || externalRef.isBlank()) {\n    throw new IllegalArgumentException(\"decisionKey variable must be set before decision task activates\");\n}","typeGuard":"Object v = planItemInstance.getCaseVariables().get(\"decisionKey\");\nif (v instanceof String s && !s.isEmpty()) { /* safe to proceed */ }","tryCatchPattern":"try {\n    caseRuntimeService.completePlanItemInstance(planItemId);\n} catch (FlowableException e) {\n    if (e.getMessage().startsWith(\"Could not execute decision: no externalRef\")) {\n        log.error(\"Decision ref variable missing on case {}\", caseInstanceId);\n    }\n    throw e;\n}","preventionTips":["Set decision-ref variables in the case start form or data objects","Prefer static externalRef when the decision key is known at design time","Validate expressions against deployed case models in CI"],"tags":["cmmn","dmn","expression","null-value"],"backgroundTag":"missing-required-argument","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}