flowable/flowable-engine · error · ActivitiIllegalArgumentException

ProcessInstanceId cannot be null.

Error message

ProcessInstanceId cannot be null.

What it means

AbstractSetProcessInstanceStateCmd.execute validates that an execution (process instance) id was supplied before suspending or activating a process instance. A null id means the operation is impossible, so it throws ActivitiIllegalArgumentException immediately.

Solutions

  1. Ensure the process instance id is resolved before calling suspend/activate (e.g. from ProcessInstance.getId() or a runtime query).
  2. Add a caller-side null/empty check on the id before invoking the API.
  3. Check that the variable you pass is actually the process instance id, not the business key or task id.

Example fix

// before
runtimeService.suspendProcessInstanceById(instanceId); // instanceId may be null
// after
if (instanceId == null || instanceId.isEmpty()) { throw new IllegalArgumentException("instanceId required"); }
runtimeService.suspendProcessInstanceById(instanceId);
Defensive patterns

Strategy: type-guard

Validate before calling

if (instanceId == null || instanceId.trim().isEmpty()) {
    throw new IllegalArgumentException("processInstanceId is required");
}

Type guard

boolean hasProcessInstanceId(String id) { return id != null && !id.trim().isEmpty(); }

Try / catch

try {
    runtimeService.suspendProcessInstanceById(id);
} catch (ActivitiIllegalArgumentException e) {
    if ("ProcessInstanceId cannot be null.".equals(e.getMessage())) {
        logger.error("No process instance id supplied");
    } else { throw e; }
}

Prevention

When it happens

Trigger: Calling RuntimeService.suspendProcessInstanceById(null) or activateProcessInstanceById(null), or building a suspend/activate process instance command programmatically without setting the execution id.

Common situations: A variable holding the process instance id was never populated (e.g. upstream lookup returned null); a DTO field left unset; passing the wrong variable (null businessKey instead of instance id).

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

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

import org.flowable.job.api.Job;

/**
 * @author Daniel Meyer
 * @author Joram Barrez
 */
public abstract class AbstractSetProcessInstanceStateCmd implements Command<Void> {

    protected final String executionId;

    public AbstractSetProcessInstanceStateCmd(String executionId) {
        this.executionId = executionId;
    }

    @Override
    public Void execute(CommandContext commandContext) {

        if (executionId == null) {
            throw new ActivitiIllegalArgumentException("ProcessInstanceId cannot be null.");
        }

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

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

        SuspensionStateUtil.setSuspensionState(executionEntity, getNewState());

        // All child executions are suspended
        List<ExecutionEntity> childExecutions = commandContext.getExecutionEntityManager().findChildExecutionsByProcessInstanceId(executionId);
        for (ExecutionEntity childExecution : childExecutions) {
            if (!childExecution.getId().equals(executionId)) {
                SuspensionStateUtil.setSuspensionState(childExecution, getNewState());

View on GitHub (pinned to d6d39ce1c6)