flowable/flowable-engine · error · FlowableException

No startFormHandler defined in process definition '

Error message

No startFormHandler defined in process definition '

What it means

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.

Solutions

  1. Add a form definition reference to the start event: <startEvent flowable:formKey="myForm" flowable:formFieldValidation="true"/> and redeploy
  2. Use the form-engine API getStartFormModel/getStartFormMetadata (GetStartFormModelCmd) instead of legacy getStartFormData when forms live in the Flowable form engine
  3. Guard with a check for formKey via ProcessDefinitionUtil.getBpmnModel(...) start event formKey before calling
  4. Register a custom StartFormHandler via processEngineConfiguration.setStartFormHandlerFactory if forms are produced programmatically

Example fix

// before
StartFormData form = formService.getStartFormData(processDefinition.getId()); // NPEs/throws when no handler
// after
StartEvent start = (StartEvent) ProcessDefinitionUtil.getBpmnModel(pd.getId()).getMainProcess().getFlowElement("startEvent1");
if (start.getAttributes().containsKey("formKey")) {
    StartFormData form = formService.getStartFormData(pd.getId());
}
Defensive patterns

Strategy: validation

Validate before calling

StartEvent start = (StartEvent) ProcessDefinitionUtil.getBpmnModel(pdId)
        .getMainProcess().getInitialFlowElement();
boolean hasForm = start.getAttributes() != null
        && start.getAttributes().containsKey("formKey");

Type guard

boolean hasStartForm(BpmnModel model) {
    if (model == null || model.getMainProcess() == null) return false;
    StartEvent se = (StartEvent) model.getMainProcess().getInitialFlowElement();
    return se != null && se.getAttributes() != null && se.getAttributes().containsKey("formKey");
}

Try / catch

try {
    return formService.getStartFormData(pdId);
} catch (FlowableException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("No startFormHandler")) {
        return null; // definition legitimately has no start form
    }
    throw e;
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/GetStartFormCmd.java:55

    public GetStartFormCmd(String processDefinitionId) {
        this.processDefinitionId = processDefinitionId;
    }

    @Override
    public StartFormData execute(CommandContext commandContext) {
        ProcessDefinition processDefinition = CommandContextUtil.getProcessEngineConfiguration(commandContext).getDeploymentManager().findDeployedProcessDefinitionById(processDefinitionId);
        if (processDefinition == null) {
            throw new FlowableObjectNotFoundException("No process definition found for id '" + processDefinitionId + "'", ProcessDefinition.class);
        }

        if (Flowable5Util.isFlowable5ProcessDefinition(processDefinition, commandContext)) {
            return Flowable5Util.getFlowable5CompatibilityHandler().getStartFormData(processDefinitionId);
        }

        FormHandlerHelper formHandlerHelper = CommandContextUtil.getProcessEngineConfiguration(commandContext).getFormHandlerHelper();
        StartFormHandler startFormHandler = formHandlerHelper.getStartFormHandler(commandContext, processDefinition);
        if (startFormHandler == null) {
            throw new FlowableException("No startFormHandler defined in process definition '" + processDefinitionId + "'");
        }

        return startFormHandler.createStartFormData(processDefinition);
    }

}

View on GitHub (pinned to d6d39ce1c6)