{"record":{"id":"5b84662bd0930e21","repo":"flowable/flowable-engine","slug":"process-definition-does-not-have-a-form-defined","errorCode":null,"errorMessage":"Process definition does not have a form defined: \" + processDefinition.getId()","messagePattern":"Process definition does not have a form defined: \" \\+ processDefinition\\.getId\\(\\)","errorType":"http","errorClass":"FlowableObjectNotFoundException","httpStatus":404,"severity":"error","filePath":"modules/flowable-rest/src/main/java/org/flowable/rest/service/api/repository/ProcessDefinitionResource.java","lineNumber":220,"sourceCode":"        FlowElement startElement = process.getInitialFlowElement();\n        if (startElement instanceof StartEvent) {\n            StartEvent startEvent = (StartEvent) startElement;\n            if (StringUtils.isNotEmpty(startEvent.getFormKey())) {\n                if (startEvent.isSameDeployment()) {\n                    Deployment deployment = repositoryService.createDeploymentQuery().deploymentId(processDefinition.getDeploymentId()).singleResult();\n                    formInfo = formRepositoryService.getFormModelByKeyAndParentDeploymentId(startEvent.getFormKey(),\n                    \t\tdeployment.getParentDeploymentId(), processDefinition.getTenantId(), processEngineConfiguration.isFallbackToDefaultTenant());\n                    \n                } else {\n                    formInfo = formRepositoryService.getFormModelByKey(startEvent.getFormKey(), processDefinition.getTenantId(),\n                            processEngineConfiguration.isFallbackToDefaultTenant());\n                }\n            }\n        }\n\n        if (formInfo == null) {\n            // Definition found, but no form attached\n            throw new FlowableObjectNotFoundException(\"Process definition does not have a form defined: \" + processDefinition.getId());\n        }\n        \n        return formInfo;\n    }\n\n    protected ProcessDefinitionResponse activateProcessDefinition(ProcessDefinition processDefinition, boolean suspendInstances, Date date) {\n        if (!repositoryService.isProcessDefinitionSuspended(processDefinition.getId())) {\n            throw new FlowableConflictException(\"Process definition with id '\" + processDefinition.getId() + \" ' is already active\");\n        }\n        repositoryService.activateProcessDefinitionById(processDefinition.getId(), suspendInstances, date);\n\n        ProcessDefinitionResponse response = restResponseFactory.createProcessDefinitionResponse(processDefinition);\n\n        // No need to re-fetch the ProcessDefinition, just alter the suspended\n        // state of the result-object\n        response.setSuspended(false);\n        return response;\n    }","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-rest/src/main/java/org/flowable/rest/service/api/repository/ProcessDefinitionResource.java#L202-L238","documentation":"getStartForm looks up the form attached to a process definition (form key / form info). If the definition exists but no start form is defined, Flowable throws FlowableObjectNotFoundException rather than returning an empty form.","triggerScenarios":"GET /repository/process-definitions/{id}/startform (formInfo) for a definition whose start event has no flowable:formKey / no form definition resolved.","commonSituations":"Models authored without a start-form key; form deployments removed or not deployed to the same engine; form resolution failing silently so formInfo stays null.","solutions":["Add a flowable:formKey (or form definition reference) to the process start event and redeploy","Deploy the referenced form model to the engine","Treat 404 for startform as 'no form configured' in client code"],"exampleFix":"// before\n<startEvent id=\"start\" />\n// after\n<startEvent id=\"start\" flowable:formKey=\"startForm\" />","handlingStrategy":"try-catch","validationCode":"const model = await getBpmnModel(defId);\nconst hasFormKey = model.startEvents.some(se => se.formKey != null);","typeGuard":"const hasStartForm = (def) => def != null && def.formKey != null;","tryCatchPattern":"try { form = await api.getStartForm(defId); }\ncatch (e) { if (e.status === 404) form = null; /* no form configured */ else throw e; }","preventionTips":["Set flowable:formKey on start events when forms are required","Deploy form models together with process definitions","Treat 404 on startform as 'no form' rather than an unexpected fault"],"tags":["rest","forms","not-found"],"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"}