flowable/flowable-engine · error · FlowableException

Cannot set suspension state for execution '{executionEntity}

Error message

Cannot set suspension state for execution '{executionEntity}': not a process instance.

What it means

FlowableException thrown by AbstractSetProcessInstanceStateCmd.execute when the id supplied to activate/suspend resolves to an execution that exists but is not of type process instance (e.g. a child/concurrent execution or a task execution). Only the root execution representing the whole process instance may have its suspension state changed this way.

Source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/AbstractSetProcessInstanceStateCmd.java:67

        this.processInstanceId = processInstanceId;
    }

    @Override
    public Void execute(CommandContext commandContext) {

        if (processInstanceId == null) {
            throw new FlowableIllegalArgumentException("ProcessInstanceId cannot be null.");
        }

        ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
        ExecutionEntityManager executionEntityManager = processEngineConfiguration.getExecutionEntityManager();
        ExecutionEntity executionEntity = executionEntityManager.findById(processInstanceId);

        if (executionEntity == null) {
            throw new FlowableObjectNotFoundException("Cannot find processInstance for id '" + processInstanceId + "'.", Execution.class);
        }
        if (!executionEntity.isProcessInstanceType()) {
            throw new FlowableException("Cannot set suspension state for execution '" + executionEntity + "': not a process instance.");
        }

        if (Flowable5Util.isFlowable5ProcessDefinitionId(commandContext, executionEntity.getProcessDefinitionId())) {
            if (getNewState() == SuspensionState.ACTIVE) {
                processEngineConfiguration.getFlowable5CompatibilityHandler().activateProcessInstance(processInstanceId);
            } else {
                processEngineConfiguration.getFlowable5CompatibilityHandler().suspendProcessInstance(processInstanceId);
            }
            return null;
        }

        SuspensionStateUtil.setSuspensionState(executionEntity, getNewState());
        executionEntityManager.update(executionEntity, false);

        // All child executions are suspended
        Collection<ExecutionEntity> childExecutions = executionEntityManager.findChildExecutionsByProcessInstanceId(processInstanceId);
        for (ExecutionEntity childExecution : childExecutions) {
            if (!childExecution.getId().equals(processInstanceId)) {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Query the process instance id instead: runtimeService.createProcessInstanceQuery().processInstanceId(execution.getProcessInstanceId()).
  2. From an Execution object, use getProcessInstanceId() (or getRootProcessInstanceId()) rather than getId().
  3. Validate execution.isProcessInstanceType() (via a query on ExecutionQuery.processInstanceId) before calling the suspend/activate API.
  4. Use runtimeService.createExecutionQuery().executionId(id).singleResult() to inspect the type of the id you hold.

Example fix

// before
Execution e = executions.get(0); // child execution
runtimeService.suspendProcessInstanceById(e.getId());
// after
runtimeService.suspendProcessInstanceById(e.getProcessInstanceId());
Defensive patterns

Strategy: validation

Validate before calling

Execution e = runtimeService.createExecutionQuery().executionId(id).singleResult();
if (e == null || !e.getId().equals(e.getProcessInstanceId())) {
    throw new IllegalArgumentException("Not a process instance id: " + id);
}

Try / catch

try {
    runtimeService.activateProcessInstanceById(id);
} catch (FlowableException e) {
    if (e.getMessage().contains("not a process instance")) {
        runtimeService.activateProcessInstanceById(
            runtimeService.createExecutionQuery().executionId(id).singleResult().getProcessInstanceId());
    }
}

Prevention

When it happens

Trigger: Calling runtimeService.activateProcessInstanceById(id)/suspendProcessInstanceById(id) with an executionId (from a sub-execution or concurrent branch) instead of the processInstance's own id.

Common situations: Copying an executionId from an ExecutionQuery result of a nested scope; ids taken from activity-level listeners; mixing execution and process-instance APIs.

Related errors


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