flowable/flowable-engine · error · FlowableIllegalArgumentException

The process instance id is mandatory, but '" +…

Error message

The process instance id is mandatory, but '" + processInstanceId + "' has been provided."

What it means

The ProcessInstanceClaimCmd constructor validates its arguments eagerly: if processInstanceId is null or an empty string, it throws FlowableIllegalArgumentException before any command context exists. Claiming (attaching a userId identity link to) a process instance requires a real instance id.

Solutions

  1. Validate processInstanceId with a null/empty check before constructing the command.
  2. Fix the upstream source (REST handler, query result) that produced the blank id.
  3. Catch FlowableIllegalArgumentException at the command-dispatch boundary and return a 400-level validation error.
  4. Use a domain helper that refuses to build the command for blank ids, keeping the check in one place.

Example fix

// before
managementService.executeCommand(new ProcessInstanceClaimCmd(processInstanceId, userId));
// after
if (processInstanceId == null || processInstanceId.isEmpty()) {
    throw new IllegalArgumentException("processInstanceId is required");
}
managementService.executeCommand(new ProcessInstanceClaimCmd(processInstanceId, userId));
Defensive patterns

Strategy: validation

Validate before calling

Objects.requireNonNull(processInstanceId, "processInstanceId is required");
if (processInstanceId.isEmpty()) { throw new IllegalArgumentException("processInstanceId must not be empty"); }

Type guard

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

Try / catch

try {
    managementService.executeCommand(new ProcessInstanceClaimCmd(pid, userId));
} catch (FlowableIllegalArgumentException e) {
    throw new BadRequestException("A non-empty processInstanceId is required");
}

Prevention

When it happens

Trigger: new ProcessInstanceClaimCmd(null, userId) or new ProcessInstanceClaimCmd("", userId), typically executed via ManagementService/CommandRunner.

Common situations: Binding the processInstanceId from a request path/body that was empty; a null result from a previous lookup passed straight into the command; Spring bean wiring calling the command with an unresolved property.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/ProcessInstanceClaimCmd.java:45

import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.engine.impl.util.IdentityLinkUtil;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.identitylink.api.IdentityLinkType;
import org.flowable.identitylink.service.impl.persistence.entity.IdentityLinkEntity;

/**
 * {@link Command} that claims an existing process instance.
 */
public class ProcessInstanceClaimCmd implements Command<Void>, Serializable {

    private static final long serialVersionUID = 1L;

    private final String processInstanceId;
    private final String userId;

    public ProcessInstanceClaimCmd(String processInstanceId, String userId) {
        if (processInstanceId == null || processInstanceId.isEmpty()) {
            throw new FlowableIllegalArgumentException("The process instance id is mandatory, but '" + processInstanceId + "' has been provided.");
        }

        this.processInstanceId = processInstanceId;
        this.userId = userId;
    }

    @Override
    public Void execute(CommandContext commandContext) {
        ExecutionEntityManager executionManager = CommandContextUtil.getExecutionEntityManager(commandContext);
        ExecutionEntity processInstance = executionManager.findById(processInstanceId);
        if (processInstance == null) {
            throw new FlowableObjectNotFoundException("No process instance found for id = '" + processInstanceId + "'.", ProcessInstance.class);

        } else if (!processInstance.isProcessInstanceType()) {
            throw new FlowableIllegalArgumentException("A process instance id is required, but the provided id " + "'" + processInstanceId + "' " + "points to a child execution of process instance " + "'"
                    + processInstance.getProcessInstanceId() + "'. " + "Please invoke the " + getClass().getSimpleName() + " with a root execution id.");
        }

View on GitHub (pinned to d6d39ce1c6)