flowable/flowable-engine · error · FlowableException

Execution '<execution>' is not a processInstance

Error message

Execution '<execution>' is not a processInstance

What it means

FlowableProcessTerminatedEventImpl models completion of a process instance via a terminate end event. Its constructor requires the passed execution to be of process-instance type; if not, it throws FlowableException because terminate events are scoped to the process instance execution only.

Source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/delegate/event/impl/FlowableProcessTerminatedEventImpl.java:33

import org.flowable.common.engine.api.FlowableException;
import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType;
import org.flowable.common.engine.api.scope.ScopeTypes;
import org.flowable.engine.delegate.event.FlowableProcessTerminatedEvent;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;

/**
 * An {@link FlowableProcessTerminatedEvent} implementation.
 *
 * @author martin.grofcik
 */
public class FlowableProcessTerminatedEventImpl extends FlowableEntityEventImpl implements FlowableProcessTerminatedEvent {

    protected Object cause;

    public FlowableProcessTerminatedEventImpl(ExecutionEntity execution, Object cause) {
        super(execution, FlowableEngineEventType.PROCESS_COMPLETED_WITH_TERMINATE_END_EVENT);
        if (!execution.isProcessInstanceType()) {
            throw new FlowableException("Execution '"+ execution +"' is not a processInstance");
        }
        
        this.subScopeId = execution.getId();
        this.scopeId = execution.getProcessInstanceId();
        this.scopeDefinitionId = execution.getProcessDefinitionId();
        this.scopeType = ScopeTypes.BPMN;
        this.cause = cause;
    }

    @Override
    public Object getCause() {
        return cause;
    }

}

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Pass the process instance execution (execution.getProcessInstanceId() / root execution) instead of a child scope execution
  2. Check execution.isProcessInstanceType() before constructing the event
  3. When handling termination in a listener, resolve ExecutionEntityManager to fetch the process instance execution

Example fix

// before
new FlowableProcessTerminatedEventImpl(execution, cause);
// after
ExecutionEntity pi = execution.isProcessInstanceType()
    ? execution
    : execution.getProcessInstance();
new FlowableProcessTerminatedEventImpl(pi, cause);
Defensive patterns

Strategy: validation

Validate before calling

if (!execution.isProcessInstanceType()) { throw new IllegalArgumentException("terminate event requires process instance execution"); }

Type guard

boolean isProcessInstance = execution.isProcessInstanceType();

Try / catch

try { new FlowableProcessTerminatedEventImpl(execution, cause); } catch (FlowableException e) { /* resolve process instance and retry */ }

Prevention

When it happens

Trigger: Constructing this event with an ExecutionEntity whose isProcessInstanceType() is false — e.g. a child/concurrent scope execution (embedded sub-process branch or call-activity child) rather than the root process instance execution.

Common situations: Custom event dispatching during process termination that picks the wrong execution from the execution tree; integrations logging terminate-end-event behavior using a nested execution reference.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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