flowable/flowable-engine · error · FlowableException
Could not execute decision: no externalRef defined for ${pla
Error message
Could not execute decision: no externalRef defined for ${planItemInstanceEntity} What it means
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.
Source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/behavior/impl/DecisionTaskActivityBehavior.java:79
DmnDecisionService dmnRuleService = CommandContextUtil.getDmnRuleService(commandContext);
if (dmnRuleService == null) {
throw new FlowableException("Could not execute decision instance: no dmn service found. For " + planItemInstanceEntity);
}
String externalRef = null;
if (decisionTask != null && decisionTask.getDecision() != null &&
StringUtils.isNotEmpty(decisionTask.getDecision().getExternalRef())) {
externalRef = decisionTask.getDecision().getExternalRef();
} else if (decisionRefExpression != null) {
Object externalRefValue = decisionRefExpression.getValue(planItemInstanceEntity);
if (externalRefValue != null) {
externalRef = externalRefValue.toString();
}
if (StringUtils.isEmpty(externalRef)) {
throw new FlowableException("Could not execute decision: no externalRef defined for " + planItemInstanceEntity);
}
}
CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);
ExecuteDecisionBuilder executeDecisionBuilder = dmnRuleService.createExecuteDecisionBuilder().
decisionKey(externalRef).
instanceId(planItemInstanceEntity.getCaseInstanceId()).
executionId(planItemInstanceEntity.getId()).
activityId(decisionTask.getId()).
scopeType(ScopeTypes.CMMN).
variables(planItemInstanceEntity.getVariables()).
tenantId(planItemInstanceEntity.getTenantId());
String fallBackToDefaultTenantValue = getFieldString(STRING_DECISION_TABLE_FALLBACK_TO_DEFAULT_TENANT);
if (Boolean.parseBoolean(fallBackToDefaultTenantValue)) {
executeDecisionBuilder.fallbackToDefaultTenant();
}
View on GitHub (pinned to d6d39ce1c6)
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.
Example fix
// before: activates with missing variable caseRuntimeService.setVariable(caseInstanceId, "decisonKey", "myDecision"); // typo -> expression yields null // after caseRuntimeService.setVariable(caseInstanceId, "decisionKey", "myDecision");
Defensive patterns
Strategy: validation
Validate before calling
String externalRef = (String) caseInstance.getCaseVariables().get("decisionKey");
if (externalRef == null || externalRef.isBlank()) {
throw new IllegalArgumentException("decisionKey variable must be set before decision task activates");
} Type guard
Object v = planItemInstance.getCaseVariables().get("decisionKey");
if (v instanceof String s && !s.isEmpty()) { /* safe to proceed */ } Try / catch
try {
caseRuntimeService.completePlanItemInstance(planItemId);
} catch (FlowableException e) {
if (e.getMessage().startsWith("Could not execute decision: no externalRef")) {
log.error("Decision ref variable missing on case {}", caseInstanceId);
}
throw e;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Unable to resolve expression value for ${value} in ${planIte
- DMN decision with key ${externalRef} execution failed. For $
- Could not resolve key from expression:
- Expression
- decisionTableReferenceKey expression resolves to an empty va
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/431af28f70526bc1.
Report an issue: GitHub.