flowable/flowable-engine · error · ActivitiException

Cannot execution operation because execution '" +…

Error message

Cannot execution operation because execution '" + executionId + "' is suspended

What it means

Thrown when the execution identified by executionId exists but is in suspended state. NeedsActiveExecutionCmd.execute() explicitly blocks operations on suspended executions with an ActivitiException whose message comes from getSuspendedExceptionMessage(). The execution must be activated before the operation can proceed.

Solutions

  1. Resume the instance/execution first: runtimeService.activateProcessInstanceById(processInstanceId) (or activateProcessDefinitionById for definition-level suspension).
  2. Check suspension state before the call: runtimeService.createProcessInstanceQuery().processInstanceId(pid).singleResult().isSuspended().
  3. If the suspension was intentional, queue or defer the operation (e.g. delay the signal/job) until the instance is reactivated.
  4. Review job/async executor settings so suspended instances' jobs are not retried into user-visible errors.

Example fix

// before
runtimeService.signal(executionId);

// after
Execution execution = runtimeService.createExecutionQuery().executionId(executionId).singleResult();
ProcessInstance pi = runtimeService.createProcessInstanceQuery()
    .processInstanceId(execution.getProcessInstanceId()).singleResult();
if (pi.isSuspended()) {
    runtimeService.activateProcessInstanceById(pi.getId());
}
runtimeService.signal(executionId);
Defensive patterns

Strategy: validation

Validate before calling

ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(pid).singleResult();
if (pi != null && pi.isSuspended()) runtimeService.activateProcessInstanceById(pid);

Try / catch

try {
    runtimeService.signal(executionId);
} catch (ActivitiException e) {
    if (e.getMessage() != null && e.getMessage().contains("is suspended")) {
        runtimeService.activateProcessInstanceById(processInstanceId);
    }
}

Prevention

When it happens

Trigger: Any command extending NeedsActiveExecutionCmd (signal, trigger, setting variables on the execution, etc.) executed while the execution's process instance or definition was suspended via runtimeService.suspendProcessInstanceById / suspendProcessDefinitionById.

Common situations: Administrator suspended a process definition for a release/migration and ongoing instances got suspended; a timer or message arrives for a suspended instance; test environments left suspended from previous runs.

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

Appendix: source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/NeedsActiveExecutionCmd.java:53

        this.executionId = executionId;
    }

    @Override
    public T execute(CommandContext commandContext) {
        if (executionId == null) {
            throw new ActivitiIllegalArgumentException("executionId is null");
        }

        ExecutionEntity execution = commandContext
                .getExecutionEntityManager()
                .findExecutionById(executionId);

        if (execution == null) {
            throw new ActivitiObjectNotFoundException("execution " + executionId + " doesn't exist", Execution.class);
        }

        if (execution.isSuspended()) {
            throw new ActivitiException(getSuspendedExceptionMessage());
        }

        return execute(commandContext, execution);
    }

    /**
     * Subclasses should implement this method. The provided {@link ExecutionEntity} is guaranteed to be active (ie. not suspended).
     */
    protected abstract T execute(CommandContext commandContext, ExecutionEntity execution);

    /**
     * Subclasses can override this to provide a more detailed exception message that will be thrown when the execution is suspended.
     */
    protected String getSuspendedExceptionMessage() {
        return "Cannot execution operation because execution '" + executionId + "' is suspended";
    }

}

View on GitHub (pinned to d6d39ce1c6)