flowable/flowable-engine · warning

Could not create conclusion result

Error message

Could not create conclusion result

What it means

In RuleEngineExecutorImpl.composeOutputEntryResult, the DMN engine evaluates an output entry expression and converts the result into an execution variable. If the resulting executionVariable is null (expression evaluated to nothing / conversion produced null), the engine cannot create a conclusion result and logs this warning; audit/decision results will lack that output entry.

Solutions

  1. Check the DMN decision table: ensure the output entry expression actually produces a value for the matching rule, or mark the output as conditional/optional.
  2. Verify output variable type (outputVariableType) matches the expression result type; fix the DMN model's type declarations.
  3. Enable debug logging ('Created conclusion result') on passing rules to compare with the failing one and find which expression returns null.
  4. Ensure required input variables are set on the DecisionExecution/variables map so output expressions don't evaluate to null.
  5. Wrap the failing expression defensively in the DMN model (e.g. defaults) or provide a fallback output value in the rule.

Example fix

// before (DMN output expression may yield nothing)
<outputEntry expressionLanguage="juel"><text>someOptionalValue</text></outputEntry>
// after (provide a default)
<outputEntry expressionLanguage="juel"><text>someOptionalValue != null ? someOptionalValue : 'default'</text></outputEntry>
Defensive patterns

Strategy: validation

Validate before calling

// before executeDecision: verify all inputs used by output entries are present and non-null
for (String required : List.of("amount", "riskScore")) {
    if (variables.get(required) == null) throw new IllegalArgumentException("Missing DMN input: " + required);
}

Type guard

boolean hasConclusion(DecisionService decisionService, String decisionKey, Map<String,Object> vars) {
    List<Map<String,Object>> results = decisionService.executeDecisionWithVariables(decisionKey, vars)
        .getRuleExecutions(); // then check each rule's output entries are non-null before use
    return results != null && results.stream().allMatch(r -> r.get("output") != null);
}

Try / catch

try {
    DecisionExecutionAuditContainer audit = decisionService.executeDecisionWithAuditContainer(key, vars);
    if (audit.getDecisionResult() == null || audit.getDecisionResult().isEmpty()) {
        LOGGER.warn("No conclusion result produced; check output entries and types");
    }
} catch (FlowableException e) {
    LOGGER.error("DMN execution failed", e);
}

Prevention

When it happens

Trigger: Executing a decision table (executeOutputEntryAction) where an output entry expression evaluates to null or fails type conversion, e.g. hit policy expects a value but the expression returns nothing, or the output variable type does not match the evaluated value.

Common situations: DMN output expressions referencing missing input data (FEEL/JUEL evaluation yielding null); output type declared as long/date while the expression returns a string that cannot convert; hit-policies (e.g. single) combined with conditional outputs that don't fire; empty cells in decision table output columns.

Related errors


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

Appendix: source

Thrown at modules/flowable-dmn-engine/src/main/java/org/flowable/dmn/engine/impl/RuleEngineExecutorImpl.java:271

                Object resultValue = ELExpressionExecutor.executeOutputExpression(ruleClauseContainer.getOutputClause(), outputEntryExpression, expressionManager, executionContext);
                executionVariable = ExecutionVariableFactory.getExecutionVariable(outputVariableType, resultValue);

                // update execution context
                executionContext.getStackVariables().put(outputVariableId, executionVariable);

                // create result
                if (getHitPolicyBehavior(hitPolicy) instanceof ComposeRuleResultBehavior) {
                    ((ComposeRuleResultBehavior) getHitPolicyBehavior(hitPolicy)).composeRuleResult(ruleNumber, outputVariableId, executionVariable, executionContext);
                }

                // add audit entry
                executionContext.getAuditContainer().addOutputEntry(ruleNumber, outputEntryExpression.getId(), executionVariable);
                executionContext.getAuditContainer().addDecisionResultType(outputVariableId, outputVariableType);

                if (executionVariable != null) {
                    LOGGER.debug("Created conclusion result: {} of type: {} with value {}", outputVariableId, resultValue.getClass(), resultValue);
                } else {
                    LOGGER.warn("Could not create conclusion result");
                }

            } catch (FlowableException ade) {
                // clear result variables
                executionContext.getRuleResults().clear();

                // add failed audit entry and rethrow
                executionContext.getAuditContainer().addOutputEntry(ruleNumber, outputEntryExpression.getId(), getExceptionMessage(ade), executionVariable);
                throw ade;

            } catch (Exception e) {
                // clear result variables
                executionContext.getRuleResults().clear();

                // add failed audit entry and rethrow
                executionContext.getAuditContainer().addOutputEntry(ruleNumber, outputEntryExpression.getId(), getExceptionMessage(e), executionVariable);
                throw new FlowableException(getExceptionMessage(e), e);
            }

View on GitHub (pinned to d6d39ce1c6)