flowable/flowable-engine · error · FlowableObjectNotFoundException

No decision found for key

Error message

No decision found for key <decisionKey>.

What it means

Thrown when a decision is resolved by decisionKey alone (no parent deployment, no tenant) and findLatestDecisionByKey returns null — i.e. no decision with that key is deployed anywhere in the DMN repository. Execution cannot continue without a definition.

Solutions

  1. Deploy the DMN resource containing the decision (DmnRepositoryService.createDeployment().addClasspathResource("x.dmn").deploy()).
  2. Fix the decisionKey to match the decision id in the .dmn XML.
  3. Confirm with dmnRepositoryService.createDecisionQuery().decisionKey(key).latestVersion().singleResult() before executing.
  4. Check you are connected to the database/schema where the decision is deployed.

Example fix

// before
dmnEngineRule.executeDecision(new ExecuteDecisionBuilderImpl().decisionKey("approveOrder"));
// after
if (dmnRepositoryService.createDecisionQuery().decisionKey("approveOrder").count() == 0) {
    dmnRepositoryService.createDeployment().addClasspathResource("dmn/approveOrder.dmn").deploy();
}
dmnEngineRule.executeDecision(new ExecuteDecisionBuilderImpl().decisionKey("approveOrder"));
Defensive patterns

Strategy: validation

Validate before calling

if (dmnRepositoryService.createDecisionQuery().decisionKey(key).latestVersion().singleResult() == null) {
    dmnRepositoryService.createDeployment().addClasspathResource("dmn/" + key + ".dmn").deploy();
}

Try / catch

try { dmnEngine.executeDecision(builder.decisionKey(key)); }
catch (FlowableObjectNotFoundException e) { log.error("Decision {} not deployed", key, e); throw new IllegalStateException("Deploy DMN model first", e); }

Prevention

When it happens

Trigger: Calling executeDecision / evaluateDecision with only decisionKey set, where no Decision entity with that key exists in the database.

Common situations: Typo in the decision key; DMN model not deployed yet; deployment auto-cleanup removed it; key refers to a decision-table id that changed when the .dmn was edited; wrong database/schema (test vs prod).

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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

Appendix: source

Thrown at modules/flowable-dmn-engine/src/main/java/org/flowable/dmn/engine/impl/cmd/AbstractExecuteDecisionCmd.java:170

                    } else {
                        decision = decisionEntityManager.findLatestDecisionByKey(decisionKey);
                        if (decision == null) {
                            throw new FlowableObjectNotFoundException("No decision found for key: " + decisionKey +
                                ". There was also no fall back decision found without tenant.");
                        }
                    }

                } else {
                    throw new FlowableObjectNotFoundException(
                        "No decision found for key: " + decisionKey + " and tenantId: " + tenantId + ".");
                }
            }

        } else if (StringUtils.isNotEmpty(decisionKey)) {
            decision = decisionEntityManager.findLatestDecisionByKey(decisionKey);
            if (decision == null) {
                throw new FlowableObjectNotFoundException("No decision found for key: " + decisionKey + ".");
            }
            
        } else {
            throw new FlowableIllegalArgumentException("decisionKey is null");
        }

        executeDecisionContext.setDecisionId(decision.getId());
        executeDecisionContext.setDecisionVersion(decision.getVersion());
        executeDecisionContext.setDeploymentId(decision.getDeploymentId());

        DecisionCacheEntry decisionTableCacheEntry = CommandContextUtil.getDmnEngineConfiguration().getDeploymentManager().resolveDecision(decision);
        DmnDefinition dmnDefinition = decisionTableCacheEntry.getDmnDefinition();

        return dmnDefinition;
    }

    protected void execute(CommandContext commandContext, DmnDefinition definition) {
        Decision decision = definition.getDecisionById(executeDecisionContext.getDecisionKey());

View on GitHub (pinned to d6d39ce1c6)