flowable/flowable-engine · error · FlowableException

DMN decision with key ${externalRef} execution failed. For $

Error message

DMN decision with key ${externalRef} execution failed. For ${planItemInstanceEntity}

What it means

The DMN decision executed but its audit container reports isFailed(), meaning rule evaluation raised an exception. The engine rethrows this as a FlowableException with the underlying DMN exception attached as cause. Inspect the cause to see the actual rule-engine failure.

Source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/behavior/impl/DecisionTaskActivityBehavior.java:118

        if (sameDeploymentValue != null) {
            if (Boolean.parseBoolean(sameDeploymentValue)) {
                executeDecisionBuilder.parentDeploymentId(
                        CaseDefinitionUtil.getDefinitionDeploymentId(planItemInstanceEntity.getCaseDefinitionId(), cmmnEngineConfiguration));
            }
        } else {
            // backwards compatibility (always apply parent deployment id)
            executeDecisionBuilder
                    .parentDeploymentId(CaseDefinitionUtil.getDefinitionDeploymentId(planItemInstanceEntity.getCaseDefinitionId(), cmmnEngineConfiguration));
        }

        DecisionExecutionAuditContainer decisionExecutionAuditContainer = executeDecisionBuilder.executeWithAuditTrail();

        if (decisionExecutionAuditContainer == null) {
            throw new FlowableException("DMN decision with key " + externalRef + " was not executed. For " + planItemInstanceEntity);
        }
        
        if (decisionExecutionAuditContainer.isFailed()) {
            throw new FlowableException("DMN decision with key " + externalRef + " execution failed. For " + planItemInstanceEntity,
                    decisionExecutionAuditContainer.getException());
        }

        /* Throw error if there were no rules hit when the flag indicates to do this. */
        String throwErrorFieldValue = getFieldString(EXPRESSION_DECISION_TABLE_THROW_ERROR_FLAG);
        if (decisionExecutionAuditContainer.getDecisionResult().isEmpty() && throwErrorFieldValue != null) {
            if ("true".equalsIgnoreCase(throwErrorFieldValue)) {
                throw new FlowableException("DMN decision with key " + externalRef + " did not hit any rules for the provided input. For " + planItemInstanceEntity);
            
            } else if (!"false".equalsIgnoreCase(throwErrorFieldValue)) {
                Expression expression = CommandContextUtil.getExpressionManager(commandContext).createExpression(throwErrorFieldValue);
                Object expressionValue = expression.getValue(planItemInstanceEntity);
                
                if (expressionValue instanceof Boolean && ((Boolean) expressionValue)) {
                    throw new FlowableException("DMN decision with key " + externalRef + " did not hit any rules for the provided input. For " + planItemInstanceEntity);
                }
            }
        }

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Inspect the exception cause (decisionExecutionAuditContainer.getException()) for the root DMN error.
  2. Verify all decision input variables are present in the case scope with correct types before the decision task activates.
  3. Test the DMN decision standalone via dmnRuleService.createExecuteDecisionBuilder() with the same inputs to reproduce and debug.
  4. Fix the failing rule expression in the .dmn model and redeploy; ensure expression variable names match the input parameter names.

Example fix

// before: input variable missing -> rule expression fails
caseRuntimeService.startCaseInstanceWithVariables(Map.of("amount", 100)); // decision expects "orderAmount"
// after
caseRuntimeService.startCaseInstanceWithVariables(Map.of("orderAmount", 100));
Defensive patterns

Strategy: try-catch

Validate before calling

for (String input : decision.getInputParameters()) {
    if (!caseVariables.containsKey(input)) {
        throw new IllegalArgumentException("Missing DMN input variable: " + input);
    }
}

Try / catch

try {
    caseRuntimeService.triggerPlanItemInstance(planItemId);
} catch (FlowableException e) {
    if (e.getMessage().contains("execution failed") && e.getCause() != null) {
        log.error("DMN rule failure root cause", e.getCause());
    }
    throw e;
}

Prevention

When it happens

Trigger: executeWithAuditTrail() returns a DecisionExecutionAuditContainer with isFailed() == true — typically an EL/JUEL error in a rule expression, a missing input variable, or a script/expression exception inside the decision table.

Common situations: Input data objects not mapped to the decision's input parameters; rule expressions referencing undefined variables; incompatible types passed into rule conditions (e.g. string vs number); DMN expression language errors after model edits.

Related errors


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