flowable/flowable-engine · error · ActivitiException

multiple none start events or timer start events not…

Error message

multiple none start events or timer start events not supported on process definition

What it means

A process definition may have at most one initial start event of the 'none' or timer variety. During executeParse, selectInitial iterates start events and throws this ActivitiException if it encounters a second none/timer start event while the current initial is not a message start event. Multiple start events are only allowed for message/signal/timer variants per the rules encoded here.

Solutions

  1. Remove the extra none start event so the process has exactly one initial start event
  2. Convert additional start events to message, signal, or timer start events if parallel entry points are needed
  3. Validate the BPMN XML in a modeler (e.g. bpmn.io validation) before deployment
  4. Search the XML for '<startEvent' occurrences and deduplicate

Example fix

// before
<startEvent id="s1"/>
<startEvent id="s2"/>
// after
<startEvent id="s1"/>
<messageStartEvent id="s2"><messageEventDefinition messageRef="m"/></messageStartEvent>
Defensive patterns

Strategy: validation

Validate before calling

long noneStarts = model.getStartEvents().stream()
    .filter(se -> se.getEventDefinitions().isEmpty())
    .count();
if (noneStarts > 1) throw new IllegalStateException("Process must have exactly one none start event");

Try / catch

try {
  repositoryService.createDeployment().addClasspathResource(processXml).deploy();
} catch (ActivitiException e) {
  if (e.getMessage().contains("multiple none start events")) {
    throw new InvalidProcessDefinitionException("Deduplicate start events in " + processXml, e);
  } else throw e;
}

Prevention

When it happens

Trigger: Deploying a BPMN process containing two or more startEvent elements where more than one is a plain none start event (or the combination resolved by this logic violates the single-initial rule), e.g. two <startEvent id="s1"/><startEvent id="s2"/> without message/signal/timer definitions.

Common situations: Merged or copy-pasted process diagrams accidentally containing duplicate start events; tooling that appends a default start event to an existing diagram; team members editing XML directly without validation.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/bpmn/parser/handler/StartEventParseHandler.java:75

            createStartFormHandlers(bpmnParse, startEvent, (ProcessDefinitionEntity) scope);
        } else {
            createScopeStartEvent(bpmnParse, startEventActivity, startEvent);
        }
    }

    protected void selectInitial(BpmnParse bpmnParse, ActivityImpl startEventActivity, StartEvent startEvent, ProcessDefinitionEntity processDefinition) {
        if (processDefinition.getInitial() == null) {
            processDefinition.setInitial(startEventActivity);
        } else {
            // validate that there is a single none start event / timer start event:
            if (!startEventActivity.getProperty("type").equals("messageStartEvent")
                    && !startEventActivity.getProperty("type").equals("signalStartEvent")
                    && !startEventActivity.getProperty("type").equals("startTimerEvent")) {
                String currentInitialType = (String) processDefinition.getInitial().getProperty("type");
                if ("messageStartEvent".equals(currentInitialType)) {
                    processDefinition.setInitial(startEventActivity);
                } else {
                    throw new ActivitiException("multiple none start events or timer start events not supported on process definition");
                }
            }
        }
    }

    protected void createStartFormHandlers(BpmnParse bpmnParse, StartEvent startEvent, ProcessDefinitionEntity processDefinition) {
        if (processDefinition.getInitial() != null) {
            if (startEvent.getId().equals(processDefinition.getInitial().getId())) {
                StartFormHandler startFormHandler = new DefaultStartFormHandler();
                startFormHandler.parseConfiguration(startEvent.getFormProperties(), startEvent.getFormKey(), bpmnParse.getDeployment(), processDefinition);
                processDefinition.setStartFormHandler(startFormHandler);
            }
        }
    }

    protected void createProcessDefinitionStartEvent(BpmnParse bpmnParse, ActivityImpl startEventActivity, StartEvent startEvent, ProcessDefinitionEntity processDefinition) {
        if (StringUtils.isNotEmpty(startEvent.getInitiator())) {
            processDefinition.setProperty(PROPERTYNAME_INITIATOR_VARIABLE_NAME, startEvent.getInitiator());

View on GitHub (pinned to d6d39ce1c6)