flowable/flowable-engine · error · FlowableException

Could not execute decision instance: no dmn service found. F

Error message

Could not execute decision instance: no dmn service found. For ${planItemInstanceEntity}

What it means

The CMMN engine's DecisionTaskActivityBehavior executes a DMN decision when a decision (task) plan item activates. Before doing so it looks up the DmnDecisionService from the command context; if none is registered, the engine cannot execute any decision and throws this FlowableException. This almost always means the DMN engine is not wired into the CMMN engine configuration.

Source

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

    protected static final String EXPRESSION_DECISION_TABLE_THROW_ERROR_FLAG = "decisionTaskThrowErrorOnNoHits";
    protected static final String STRING_DECISION_TABLE_FALLBACK_TO_DEFAULT_TENANT = "fallbackToDefaultTenant";
    protected static final String STRING_DECISION_TABLE_SAME_DEPLOYMENT = "sameDeployment";

    protected DecisionTask decisionTask;
    protected Expression decisionRefExpression;

    public DecisionTaskActivityBehavior(Expression decisionRefExpression, DecisionTask decisionTask) {
        super(decisionTask.isBlocking(), decisionTask.getBlockingExpression());
        this.decisionTask = decisionTask;
        this.decisionRefExpression = decisionRefExpression;
    }

    @Override
    public void execute(CommandContext commandContext, PlanItemInstanceEntity planItemInstanceEntity) {
        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);
            }
        }

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Add the DMN engine dependency (org.flowable:flowable-dmn-engine or the flowable-dmn-spring-boot-starter) to your project.
  2. Register a DmnEngineConfigurator in the engine configuration so the DmnDecisionService becomes available in the command context: cmmnEngineConfiguration.setConfigurators(List.of(new DmnEngineConfigurator())) or use the Spring/Boot auto-configuration.
  3. If constructing the CmmnEngineConfiguration manually, set cmmnEngineConfiguration.setDmnEngineConfiguration(dmnEngineConfiguration).
  4. Verify the decision task's decision/externalRef resolution is what you intend; but first confirm a DMN decision with that key is deployed — deploy the DMN model with the CMMN model if needed.

Example fix

// before
CmmnEngineConfiguration cfg = new StandaloneCmmnEngineConfiguration();
cfg.buildEngine(); // decision task fails: no dmn service found
// after
CmmnEngineConfiguration cfg = new StandaloneCmmnEngineConfiguration();
DmnEngineConfigurator dmnConfigurator = new DmnEngineConfigurator();
cfg.addConfigurator(dmnConfigurator); // wires DmnDecisionService into command context
cfg.buildEngine();
Defensive patterns

Strategy: validation

Validate before calling

boolean isDmnWired(CmmnEngineConfiguration cfg) {
    return cfg != null && cfg.getDmnEngineConfiguration() != null;
}

Type guard

if (commandContext != null && CommandContextUtil.getDmnRuleService(commandContext) == null) {
    throw new IllegalStateException("DMN engine not configured for CMMN engine");
}

Try / catch

try {
    caseRuntimeService.triggerPlanItemInstance(planItemId);
} catch (FlowableException e) {
    if (e.getMessage().contains("no dmn service found")) {
        throw new ConfigurationException("Register DmnEngineConfigurator in engine config", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Executing a CMMN case containing a decision (task) plan item while CommandContextUtil.getDmnRuleService(commandContext) returns null — i.e. the DMN engine configuration was never added to the CMMN engine.

Common situations: Applications that include flowable-cmmn-engine but not flowable-dmn-engine (or flowable-dmn-spring/boot starter) on the classpath; engine configurations built without cmmnEngineConfiguration.setDmnEngineConfiguration(...) or without DmnEngineConfigurator registered in the process/cmmn engine configurators list.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


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