flowable/flowable-engine · error · FlowableObjectNotFoundException

Case definition with key '${caseDefinitionKey}' and tenantId

Error message

Case definition with key '${caseDefinitionKey}' and tenantId '${tenantId}' was not found.

What it means

FlowableObjectNotFoundException thrown when the tenant-specific lookup finds no case definition for the given key+tenantId and fallback to the default tenant is not applicable/attempted (the else branch). Unlike 332, no default-tenant fallback result exists because the fallback branch was not reached.

Source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/AbstractCaseStartEventSubscriptionCmd.java:100

            if (caseDefinition == null) {
                CmmnEngineConfiguration caseEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);
                if (caseEngineConfiguration.isFallbackToDefaultTenant()) {
                    String defaultTenant = caseEngineConfiguration.getDefaultTenantProvider().getDefaultTenant(tenantId, ScopeTypes.BPMN, caseDefinitionKey);
                    if (StringUtils.isNotEmpty(defaultTenant)) {
                        caseDefinition = caseDefinitionEntityManager.findLatestCaseDefinitionByKeyAndTenantId(caseDefinitionKey, defaultTenant);
                        
                    } else {
                        caseDefinition = caseDefinitionEntityManager.findLatestCaseDefinitionByKey(caseDefinitionKey);
                    }
                    
                    if (caseDefinition == null) {
                        throw new FlowableObjectNotFoundException("No case definition found for key '" + caseDefinitionKey +
                            "'. Fallback to default tenant was also applied.", CaseDefinition.class);
                    }
                    
                } else {
                    throw new FlowableObjectNotFoundException("Case definition with key '" + caseDefinitionKey +
                        "' and tenantId '" + tenantId + "' was not found.", CaseDefinition.class);
                }
            }
        }
        
        if (caseDefinition == null) {
            throw new FlowableIllegalArgumentException("No deployed case definition found for key '" + caseDefinitionKey + "'.");
        }
        
        return caseDefinition;
    }

    protected CaseDefinition getCaseDefinitionById(String caseDefinitionId, CommandContext commandContext) {
        CmmnRepositoryService repositoryService = CommandContextUtil.getCmmnEngineConfiguration(commandContext).getCmmnRepositoryService();

        CaseDefinition caseDefinition = repositoryService.createCaseDefinitionQuery()
            .caseDefinitionId(caseDefinitionId)
            .singleResult();

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Match the tenantId exactly to the tenant used at deployment time (check whitespace/casing).
  2. Deploy the CMMN model with the correct tenantId annotation or deploy via the tenant-aware repository API.
  3. If the definition should be tenant-independent, deploy without a tenant and use NO_TENANT_ID.

Example fix

// before
builder.caseDefinitionKey("order-case").caseDefinitionTenantId("acme"); // deployed tenant is 'ACME'
// after
builder.caseDefinitionKey("order-case").caseDefinitionTenantId("ACME");
Defensive patterns

Strategy: validation

Validate before calling

CaseDefinition cd = cmmnRepositoryService.createCaseDefinitionQuery()
    .caseDefinitionKey(key).caseDefinitionTenantId(tenantId).latestVersion().singleResult();
if (cd == null) throw new IllegalStateException("no case def for " + key + "@" + tenantId);

Try / catch

try { startForTenant(key, tenantId); }
catch (FlowableObjectNotFoundException e) { logAvailableTenants(key); throw e; }

Prevention

When it happens

Trigger: getLatestCaseDefinitionByKey(key, tenantId, ctx) with non-null tenantId (not NO_TENANT_ID) where findLatestCaseDefinitionByKeyAndTenantId(key, tenantId) returns null and the code takes the else branch directly.

Common situations: Deployments exist but are registered under a different tenantId than the one sent by the client; tenantId casing/whitespace mismatch; multi-tenant environment where the definition was never replicated to the requested 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/8200aee4507bae00. Report an issue: GitHub.