flowable/flowable-engine · error · FlowableException

is not of type process instance

Error message

${execution} is not of type process instance

What it means

EvaluateConditionalEventsCmd requires the execution it operates on to be the top-level process instance. If the execution passed to the command is a child/concurrent execution, execute() throws this FlowableException because conditional boundary/intermediate events are only evaluated at process-instance scope.

Solutions

  1. Pass the process instance execution: resolve it via execution.getProcessInstanceId() + ExecutionEntityManager.findById(), or use execution.getRootProcessInstanceId()/getProcessInstance()
  2. Verify with execution.isProcessInstanceType() before invoking the command
  3. Refactor custom code to use the RuntimeService APIs (e.g. runtimeService.createExecutionQuery().processInstanceId(...).singleResult()) rather than raw commands on arbitrary executions

Example fix

// before
commandExecutor.execute(new EvaluateConditionalEventsCmd(processInstanceId, vars), childExecution);
// after
ExecutionEntity procInst = (ExecutionEntity) runtimeService.createExecutionQuery()
    .executionId(childExecution.getProcessInstanceId()).singleResult();
commandExecutor.execute(new EvaluateConditionalEventsCmd(processInstanceId, vars), procInst);
Defensive patterns

Strategy: validation

Validate before calling

ExecutionEntity pi = execution.isProcessInstanceType() ? execution : (ExecutionEntity) runtimeService.createExecutionQuery().executionId(execution.getProcessInstanceId()).singleResult();
if (pi == null || !pi.isProcessInstanceType()) throw new IllegalStateException("need process instance execution");

Type guard

boolean isProcessInstance(Execution e) { return e instanceof ExecutionEntity ee && ee.isProcessInstanceType(); }

Try / catch

try { cmd.execute(commandContext); } catch (FlowableException e) { if (e.getMessage().contains("is not of type process instance")) { /* re-resolve root process instance and retry */ } else throw e; }

Prevention

When it happens

Trigger: Passing a child execution (e.g. a concurrent or scope execution) to the command that evaluates conditional events, instead of the process instance execution.

Common situations: Custom Java delegates or listeners that fetch an execution via ExecutionEntityManager and invoke conditional-event evaluation on the wrong execution; custom command interceptors operating on child executions after parallel gateway forks.

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

Appendix: source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/EvaluateConditionalEventsCmd.java:47

    protected Map<String, Object> processVariables;
    protected Map<String, Object> transientVariables;
    protected boolean async;

    public EvaluateConditionalEventsCmd(String processInstanceId, Map<String, Object> processVariables) {
        super(processInstanceId);
        this.processVariables = processVariables;
    }

    public EvaluateConditionalEventsCmd(String processInstanceId, Map<String, Object> processVariables, Map<String, Object> transientVariables) {
        this(processInstanceId, processVariables);
        this.transientVariables = transientVariables;
    }

    @Override
    protected Object execute(CommandContext commandContext, ExecutionEntity execution) {
        if (!execution.isProcessInstanceType()) {
            throw new FlowableException(execution + " is not of type process instance");
        }
        
        if (processVariables != null) {
            execution.setVariables(processVariables);
        }

        if (transientVariables != null) {
            execution.setTransientVariables(transientVariables);
        }

        CommandContextUtil.getAgenda(commandContext).planEvaluateConditionalEventsOperation(execution);

        return null;
    }

    @Override
    protected String getSuspendedExceptionMessagePrefix() {
        return "Cannot evaluate conditions for";

View on GitHub (pinned to d6d39ce1c6)