flowable/flowable-engine · error · FlowableObjectNotFoundException

No decision found for key <decisionKey>. There was also no f

Error message

No decision found for key <decisionKey>. There was also no fall back decision found for default tenant <defaultTenant>

What it means

While resolving a decision by key with tenant fallback enabled, Flowable first queries by key and tenant, then falls back to the configured default tenant. If even that lookup returns null, it throws FlowableObjectNotFoundException indicating no decision exists for the key in the default tenant either.

Source

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

                new DmnDeploymentQueryImpl().parentDeploymentId(parentDeploymentId));

            if (dmnDeployments != null && dmnDeployments.size() != 0) {
                decision = decisionEntityManager.findDecisionByDeploymentAndKeyAndTenantId(
                    dmnDeployments.get(0).getId(), decisionKey, tenantId);
            }

            if (decision == null) {
                // If there is no decision table found linked to the deployment id, try to find one without a specific deployment id.
                decision = decisionEntityManager.findLatestDecisionByKeyAndTenantId(decisionKey, tenantId);

                if (decision == null) {
                    // if fallback to default tenant is enabled do a final lookup query
                    if (executeDecisionContext.isFallbackToDefaultTenant() || dmnEngineConfiguration.isFallbackToDefaultTenant()) {
                        String defaultTenant = dmnEngineConfiguration.getDefaultTenantProvider().getDefaultTenant(tenantId, ScopeTypes.DMN, decisionKey);
                        if (StringUtils.isNotEmpty(defaultTenant)) {
                            decision = decisionEntityManager.findLatestDecisionByKeyAndTenantId(decisionKey, defaultTenant);
                            if (decision == null) {
                                throw new FlowableObjectNotFoundException("No decision found for key: " + decisionKey +
                                    ". There was also no fall back decision found for default tenant " + defaultTenant);
                            }
                            
                        } else {
                            decision = decisionEntityManager.findLatestDecisionByKey(decisionKey);
                            if (decision == null) {
                                throw new FlowableObjectNotFoundException("No decision found for key: " + decisionKey +
                                    ". There was also no fall back decision table found without tenant.");
                            }
                        }
                        
                    } else {
                        throw new FlowableObjectNotFoundException("No decision found for key: " + decisionKey +
                            ", parent deployment id " + parentDeploymentId + " and tenant id: " + tenantId +
                            ". There was also no fall back decision found without parent deployment id.");
                    }
                }
            }

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Verify the decision is deployed and check its TENANT_ID_ in ACT_DMN_DECISION
  2. Correct the decisionKey passed to the execute call
  3. Fix the DefaultTenantProvider to return the tenant the decision is actually deployed to
  4. Remove/disable tenant filtering or deploy the DMN file to the expected tenant

Example fix

// before
DmnEngineRule r = dmnEngine.execute(decisionKey, vars).getRuleExecutions(); // key 'myDecision'
// after
String decisionKey = "decision_fraud_check"; // exact deployed key
DmnDecision d = dmnRepositoryService.createDecisionQuery().decisionKey(decisionKey).singleResult();
Defensive patterns

Strategy: try-catch

Validate before calling

Decision d = dmnRepositoryService.createDecisionQuery()
    .decisionKey(decisionKey).decisionTenantId(tenantId).singleResult();
if (d == null && fallbackEnabled) d = dmnRepositoryService.createDecisionQuery()
    .decisionKey(decisionKey).decisionTenantId(defaultTenant).singleResult();

Try / catch

try { dmnEngine.executeDecisionByKey(tenantId, decisionKey, vars); }
catch (FlowableObjectNotFoundException e) {
  LOG.warn("decision {} not found for tenant/default; check deployments", decisionKey);
  // deploy DMN or correct the key/tenant
}

Prevention

When it happens

Trigger: resolveDefinition in AbstractExecuteDecisionCmd: isFallbackToDefaultTenant() or engine config fallback enabled; findLatestDecisionByKeyAndTenantId(key, defaultTenant) returned null; DefaultTenantProvider returned a non-empty tenant.

Common situations: Decision deployed under a different tenant than the default; decision key typo or mismatched case; deployment never performed; fallback enabled but default tenant provider points at the wrong tenant.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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