flowable/flowable-engine · error · FlowableObjectNotFoundException

Case definition does not have a start form defined

Error message

Case definition does not have a start form defined: ${caseDefinition.getId()}

What it means

getStartForm resolves the start form info for a case definition; if the definition exists but no form is attached (formInfo == null after querying the form repository), it throws FlowableObjectNotFoundException. This distinguishes 'definition found, form absent' from a missing definition.

Solutions

  1. Attach a start form to the case model and redeploy.
  2. Deploy the referenced form definition to the same tenant/engine.
  3. Verify the start event's form key matches a deployed form.
  4. Handle the 404 in the caller (e.g., show a default form) when forms are optional.
Defensive patterns

Strategy: try-catch

Validate before calling

boolean hasForm = formRepository.listFormDefinitions(tenant).stream().anyMatch(f -> f.getKey().equals(model.getFormKey()));

Try / catch

try { FormInfo fi = getStartForm(id); } catch (FlowableObjectNotFoundException e) { return defaultForm(); }

Prevention

When it happens

Trigger: GET .../case-definitions/{id}/start-form where the case model was deployed without a start form reference (no form key / form definition attached to the start event).

Common situations: Models built without forms in the Flowable modeler; form definitions deployed to another tenant/engine; form key pointing at a form that was never deployed; API version differences in form resolution.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/repository/CaseDefinitionResource.java:235

    protected FormInfo getStartForm(FormRepositoryService formRepositoryService, CaseDefinition caseDefinition) {
        FormInfo formInfo = null;
        CmmnModel cmmnModel = repositoryService.getCmmnModel(caseDefinition.getId());
        Case caze = cmmnModel.getCaseById(caseDefinition.getKey());
        Stage stage = caze.getPlanModel();
        if (StringUtils.isNotEmpty(stage.getFormKey())) {
            if (stage.isSameDeployment()) {
                CmmnDeployment deployment = repositoryService.createDeploymentQuery().deploymentId(caseDefinition.getDeploymentId()).singleResult();
                formInfo = formRepositoryService.getFormModelByKeyAndParentDeploymentId(stage.getFormKey(),
                                deployment.getParentDeploymentId(), caseDefinition.getTenantId(), cmmnEngineConfiguration.isFallbackToDefaultTenant());
            } else {
                formInfo = formRepositoryService.getFormModelByKey(stage.getFormKey(), caseDefinition.getTenantId(),
                        cmmnEngineConfiguration.isFallbackToDefaultTenant());
            }
        }

        if (formInfo == null) {
            // Definition found, but no form attached
            throw new FlowableObjectNotFoundException("Case definition does not have a start form defined: " + caseDefinition.getId());
        }
        
        return formInfo;
    }
}

View on GitHub (pinned to d6d39ce1c6)