{"record":{"id":"dd15bb8d5d4eb2ba","repo":"flowable/flowable-engine","slug":"case-definition-does-not-have-a-start-form-defined","errorCode":null,"errorMessage":"Case definition does not have a start form defined: ${caseDefinition.getId()}","messagePattern":"Case definition does not have a start form defined: (.+?)","errorType":"http","errorClass":"FlowableObjectNotFoundException","httpStatus":404,"severity":"error","filePath":"modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/repository/CaseDefinitionResource.java","lineNumber":235,"sourceCode":"    protected FormInfo getStartForm(FormRepositoryService formRepositoryService, CaseDefinition caseDefinition) {\n        FormInfo formInfo = null;\n        CmmnModel cmmnModel = repositoryService.getCmmnModel(caseDefinition.getId());\n        Case caze = cmmnModel.getCaseById(caseDefinition.getKey());\n        Stage stage = caze.getPlanModel();\n        if (StringUtils.isNotEmpty(stage.getFormKey())) {\n            if (stage.isSameDeployment()) {\n                CmmnDeployment deployment = repositoryService.createDeploymentQuery().deploymentId(caseDefinition.getDeploymentId()).singleResult();\n                formInfo = formRepositoryService.getFormModelByKeyAndParentDeploymentId(stage.getFormKey(),\n                                deployment.getParentDeploymentId(), caseDefinition.getTenantId(), cmmnEngineConfiguration.isFallbackToDefaultTenant());\n            } else {\n                formInfo = formRepositoryService.getFormModelByKey(stage.getFormKey(), caseDefinition.getTenantId(),\n                        cmmnEngineConfiguration.isFallbackToDefaultTenant());\n            }\n        }\n\n        if (formInfo == null) {\n            // Definition found, but no form attached\n            throw new FlowableObjectNotFoundException(\"Case definition does not have a start form defined: \" + caseDefinition.getId());\n        }\n        \n        return formInfo;\n    }\n}\n","sourceCodeStart":217,"sourceCodeEnd":241,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/repository/CaseDefinitionResource.java#L217-L241","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Attach a start form to the case model and redeploy.","Deploy the referenced form definition to the same tenant/engine.","Verify the start event's form key matches a deployed form.","Handle the 404 in the caller (e.g., show a default form) when forms are optional."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"boolean hasForm = formRepository.listFormDefinitions(tenant).stream().anyMatch(f -> f.getKey().equals(model.getFormKey()));","typeGuard":null,"tryCatchPattern":"try { FormInfo fi = getStartForm(id); } catch (FlowableObjectNotFoundException e) { return defaultForm(); }","preventionTips":["Attach and deploy start forms with the case model.","Keep form definitions in the same tenant/engine.","Treat missing start form as a normal optional case in callers."],"tags":["not-found","forms","rest-api"],"backgroundTag":"resource-not-found","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}