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
- 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.
- Verify output variable type (outputVariableType) matches the expression result type; fix the DMN model's type declarations.
- Enable debug logging ('Created conclusion result') on passing rules to compare with the failing one and find which expression returns null.
- Ensure required input variables are set on the DecisionExecution/variables map so output expressions don't evaluate to null.
- 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
- Declare output variable types consistent with expression results in the decision table.
- Avoid empty/conditional output cells with single hit policies, or model them as optional outputs.
- Test decision tables with representative inputs in CI using Flowable's DMN test support.
- Check audit container results for null outputs instead of assuming every matched rule yields a value.
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
- condition expression returns null
- byte array for resource
- condition expression returns non-Boolean
- Could not create execution variable
- could not create result variable
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)