flowable/flowable-engine · error · FlowableException

Could not find a none start event in dynamic sub process…

Error message

Could not find a none start event in dynamic sub process for " + processInstance

What it means

During dynamic process instance modification, InjectEmbeddedSubProcessInProcessInstanceCmd.updateExecutions() searches the newly injected sub process BPMN fragment for a none start event to seed the new child execution. If the injected fragment has no such start event, it throws FlowableException. The sub process must be enterable, so a none start event is mandatory.

Solutions

  1. Add a <startEvent> with no event definitions (a none start event) to the injected sub process fragment.
  2. Validate the dynamically built BpmnModel fragment contains exactly one none start event before injecting.
  3. If the sub process should start on an event, model it explicitly and use the appropriate injection API rather than relying on none-start behavior.
  4. Check the generated process XML/JSON for the missing startEvent element.

Example fix

// before
SubProcess subProcess = new SubProcess();
subProcess.addFlowElement(new UserTask().setId("ut1")); // no start event
// after
SubProcess subProcess = new SubProcess();
subProcess.addFlowElement(new StartEvent().setId("startSub"));
subProcess.addFlowElement(new UserTask().setId("ut1"));
subProcess.addFlowElement(new EndEvent().setId("endSub"));
Defensive patterns

Strategy: validation

Validate before calling

boolean hasNoneStartEvent(SubProcess sp) {
    return sp.getFlowElements().stream()
        .anyMatch(fe -> fe instanceof StartEvent se
            && (se.getEventDefinitions() == null || se.getEventDefinitions().isEmpty()));
}

Try / catch

try {
    modificationBuilder.injectEmbeddedSubProcess(subProcessId);
} catch (FlowableException e) {
    if (e.getMessage().contains("none start event")) {
        log.error("Injected sub process lacks a none start event: fix the BPMN fragment");
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling ProcessInstanceModificationBuilder / dynamic injection APIs (e.g. processInstanceModificationBuilder.injectEmbeddedSubProcess...) with a dynamically built SubProcess fragment whose BpmnModel has only message/timer/signal start events or no start event at all.

Common situations: Hand-built or tool-generated dynamic sub process definitions that omit the implicit none start event; copying fragments from templates where the start event was stripped; users assuming Flowable adds a default start event automatically.

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/0a1bd35d3789fb21. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/InjectEmbeddedSubProcessInProcessInstanceCmd.java:85

        ExecutionEntity subProcessExecution = executionEntityManager.createChildExecution(processInstance);
        subProcessExecution.setScope(true);
        subProcessExecution.setCurrentFlowElement(subProcess);
        CommandContextUtil.getActivityInstanceEntityManager(commandContext).recordActivityStart(subProcessExecution);
        
        ExecutionEntity childExecution = executionEntityManager.createChildExecution(subProcessExecution);
        
        StartEvent initialEvent = null;
        for (FlowElement subElement : subProcess.getFlowElements()) {
            if (subElement instanceof StartEvent startEvent) {
                if (startEvent.getEventDefinitions().size() == 0) {
                    initialEvent = startEvent;
                    break;
                }
            }
        }
        
        if (initialEvent == null) {
            throw new FlowableException("Could not find a none start event in dynamic sub process for " + processInstance);
        }
        
        childExecution.setCurrentFlowElement(initialEvent);
        
        Context.getAgenda().planContinueProcessOperation(childExecution);
    }

}

View on GitHub (pinned to d6d39ce1c6)