{"record":{"id":"eb641c31da4a1768","repo":"flowable/flowable-engine","slug":"no-startformhandler-defined-in-process-definition","errorCode":null,"errorMessage":"No startFormHandler defined in process definition '","messagePattern":"No startFormHandler defined in process definition '","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/GetStartFormCmd.java","lineNumber":55,"sourceCode":"    public GetStartFormCmd(String processDefinitionId) {\n        this.processDefinitionId = processDefinitionId;\n    }\n\n    @Override\n    public StartFormData execute(CommandContext commandContext) {\n        ProcessDefinition processDefinition = CommandContextUtil.getProcessEngineConfiguration(commandContext).getDeploymentManager().findDeployedProcessDefinitionById(processDefinitionId);\n        if (processDefinition == null) {\n            throw new FlowableObjectNotFoundException(\"No process definition found for id '\" + processDefinitionId + \"'\", ProcessDefinition.class);\n        }\n\n        if (Flowable5Util.isFlowable5ProcessDefinition(processDefinition, commandContext)) {\n            return Flowable5Util.getFlowable5CompatibilityHandler().getStartFormData(processDefinitionId);\n        }\n\n        FormHandlerHelper formHandlerHelper = CommandContextUtil.getProcessEngineConfiguration(commandContext).getFormHandlerHelper();\n        StartFormHandler startFormHandler = formHandlerHelper.getStartFormHandler(commandContext, processDefinition);\n        if (startFormHandler == null) {\n            throw new FlowableException(\"No startFormHandler defined in process definition '\" + processDefinitionId + \"'\");\n        }\n\n        return startFormHandler.createStartFormData(processDefinition);\n    }\n\n}\n","sourceCodeStart":37,"sourceCodeEnd":62,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/GetStartFormCmd.java#L37-L62","documentation":"After locating the process definition, GetStartFormCmd asks FormHandlerHelper.getStartFormHandler for the StartFormHandler configured in the definition's start element; when it is null the command throws FlowableException. This happens when the BPMN XML defines no start form handling (no startFormHandler/formKey configuration), so no start form data can be created.","triggerScenarios":"getStartFormData/processDefinitionId is called for a process whose start event has no formKey/startFormHandler (typically a start event with flowable:formKey missing and no custom StartFormHandler registered).","commonSituations":"BPMN model with a plain start event and forms managed externally (e.g. Flowable Form engine instead of embedded form properties); XML edited manually removing the flowable:formKey attribute; older processes deployed before forms were added; confusion between legacy embedded forms and the form-engine-based APIs.","solutions":["Add a form definition reference to the start event: <startEvent flowable:formKey=\"myForm\" flowable:formFieldValidation=\"true\"/> and redeploy","Use the form-engine API getStartFormModel/getStartFormMetadata (GetStartFormModelCmd) instead of legacy getStartFormData when forms live in the Flowable form engine","Guard with a check for formKey via ProcessDefinitionUtil.getBpmnModel(...) start event formKey before calling","Register a custom StartFormHandler via processEngineConfiguration.setStartFormHandlerFactory if forms are produced programmatically"],"exampleFix":"// before\nStartFormData form = formService.getStartFormData(processDefinition.getId()); // NPEs/throws when no handler\n// after\nStartEvent start = (StartEvent) ProcessDefinitionUtil.getBpmnModel(pd.getId()).getMainProcess().getFlowElement(\"startEvent1\");\nif (start.getAttributes().containsKey(\"formKey\")) {\n    StartFormData form = formService.getStartFormData(pd.getId());\n}","handlingStrategy":"validation","validationCode":"StartEvent start = (StartEvent) ProcessDefinitionUtil.getBpmnModel(pdId)\n        .getMainProcess().getInitialFlowElement();\nboolean hasForm = start.getAttributes() != null\n        && start.getAttributes().containsKey(\"formKey\");","typeGuard":"boolean hasStartForm(BpmnModel model) {\n    if (model == null || model.getMainProcess() == null) return false;\n    StartEvent se = (StartEvent) model.getMainProcess().getInitialFlowElement();\n    return se != null && se.getAttributes() != null && se.getAttributes().containsKey(\"formKey\");\n}","tryCatchPattern":"try {\n    return formService.getStartFormData(pdId);\n} catch (FlowableException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"No startFormHandler\")) {\n        return null; // definition legitimately has no start form\n    }\n    throw e;\n}","preventionTips":["Declare flowable:formKey on every start event that needs a start form and redeploy","Keep BPMN XML under version control so formKey attributes are not dropped in manual edits","Prefer the form-engine API (getStartFormModel) when your forms are stored in the Flowable form engine"],"tags":["flowable","start-form","bpmn-model"],"backgroundTag":"missing-required-config-field","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"}