flowable/flowable-engine · error · FlowableException

Expected an activity behavior in flow node ${flowNode.getId(

Error message

Expected an activity behavior in flow node ${flowNode.getId()} for ${execution}

What it means

During a synchronous multi-instance continuation, ContinueProcessOperation requires the flow node to have an attached activity behavior that can be executed. If a FlowNode reaches this multi-instance path without behavior, the engine cannot continue and throws FlowableException with the node id and execution.

Source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/agenda/ContinueProcessOperation.java:235

        if (activityBehavior != null) {
            executeActivityBehavior(activityBehavior, flowNode);
            
            if (execution.isMultiInstanceRoot() && !execution.isDeleted() && !execution.isEnded()) {
                // Create any boundary events, sub process boundary events will be created from the activity behavior
                List<ExecutionEntity> boundaryEventExecutions = null;
                List<BoundaryEvent> boundaryEvents = null;
                if (!inCompensation && flowNode instanceof Activity) { // Only activities can have boundary events
                    boundaryEvents = ((Activity) flowNode).getBoundaryEvents();
                    if (CollectionUtil.isNotEmpty(boundaryEvents)) {
                        boundaryEventExecutions = createBoundaryEvents(boundaryEvents, execution);
                    }
                }
                
                executeBoundaryEvents(boundaryEventExecutions);
            }
            
        } else {
            throw new FlowableException("Expected an activity behavior in flow node " + flowNode.getId() + " for " + execution);
        }
    }
    
    protected boolean hasMultiInstanceRootExecution(ExecutionEntity execution, FlowNode flowNode) {
        ExecutionEntity currentExecution = execution.getParent();
        while (currentExecution != null) {
            if (currentExecution.isMultiInstanceRoot() && flowNode.getId().equals(currentExecution.getActivityId())) {
                return true;
            }
            currentExecution = currentExecution.getParent();
        }
        return false;
    }
    
    protected ExecutionEntity createMultiInstanceRootExecution(ExecutionEntity execution) {
        ExecutionEntity parentExecution = execution.getParent();
        FlowElement flowElement = execution.getCurrentFlowElement();
        

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Check the node id in the message against the deployed model and confirm the element type is a supported Flowable task/node
  2. Ensure all BpmnParseHandler/extension modules used at design time are on the runtime classpath
  3. Redeploy the process definition after fixing the model or upgrading the engine
  4. If multi-instance is unnecessary, remove the multiInstanceLoopCharacteristics

Example fix

// before (bpmn)
<serviceTask id="step1" flowable:multiInstanceLoopCharacteristics="..." />
<!-- no class/delegateExpression binding -->
// after (bpmn)
<serviceTask id="step1" flowable:class="com.acme.Step1Delegate"
    flowable:multiInstanceLoopCharacteristics="..." />
Defensive patterns

Strategy: try-catch

Validate before calling

FlowNode node = (FlowNode) bpmnModel.getFlowElement(nodeId);
if (node.getBehavior() == null) {
    throw new IllegalStateException("Node " + nodeId + " has no activity behavior; check parse handlers");
}

Try / catch

try {
    // continuation happens inside engine ops
} catch (FlowableException e) {
    if (e.getMessage().contains("Expected an activity behavior")) {
        log.error("Model/parse problem at node; check deployed BPMN and parse handlers");
    }
    throw e;
}

Prevention

When it happens

Trigger: continueThroughFlowNode -> executeMultiInstanceSynchronous on a multi-instance flow node whose behavior is null — usually a custom/unknown element type, a listener-swallowed parse error, or a model element unsupported by the deployed BpmnParseHandler set.

Common situations: Custom BPMN extensions/parse handlers missing on the classpath; process XML deployed with elements the engine version does not map to behaviors; corrupted parse after version upgrade.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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