flowable/flowable-engine · error · FlowableIllegalArgumentException

A process instance id is required, but the provided id '${pr

Error message

A process instance id is required, but the provided id '${processInstanceId}' points to a child execution of process instance '${processInstance.getProcessInstanceId()}'. Please invoke the ${class simple name} with a root execution id.

What it means

execute() requires the id to reference the root process instance execution. If findById returns a child execution (e.g. a scope or concurrent execution), isProcessInstanceType() is false and it throws FlowableIllegalArgumentException directing the caller to use a root execution id.

Source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/SetProcessDefinitionVersionCmd.java:86

            throw new FlowableIllegalArgumentException("The process definition version is mandatory, but 'null' has been provided.");
        }
        if (processDefinitionVersion < 1) {
            throw new FlowableIllegalArgumentException("The process definition version must be positive, but '" + processDefinitionVersion + "' has been provided.");
        }
        this.processInstanceId = processInstanceId;
        this.processDefinitionVersion = processDefinitionVersion;
    }

    @Override
    public Void execute(CommandContext commandContext) {
        // check that the new process definition is just another version of the same
        // process definition that the process instance is using
        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.");
        }

        DeploymentManager deploymentCache = CommandContextUtil.getProcessEngineConfiguration(commandContext).getDeploymentManager();
        ProcessDefinition currentProcessDefinition = deploymentCache.findDeployedProcessDefinitionById(processInstance.getProcessDefinitionId());

        ProcessDefinition newProcessDefinition = deploymentCache
                .findDeployedProcessDefinitionByKeyAndVersionAndTenantId(currentProcessDefinition.getKey(), processDefinitionVersion, currentProcessDefinition.getTenantId());

        if (Flowable5Util.isFlowable5ProcessDefinition(currentProcessDefinition, commandContext) && !Flowable5Util
            .isFlowable5ProcessDefinition(newProcessDefinition, commandContext)) {
            throw new FlowableIllegalArgumentException("The current process definition (id = '" + currentProcessDefinition.getId() + "') is a v5 definition."
                + " However the new process definition (id = '" + newProcessDefinition.getId() + "') is not a v5 definition.");
        }

        validateAndSwitchVersionOfExecution(commandContext, processInstance, newProcessDefinition);

        // switch the historic process instance to the new process definition version

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Use execution.getProcessInstanceId() to obtain the root id before invoking the command
  2. Query process instances with RuntimeService.createProcessInstanceQuery() rather than execution queries
  3. Verify the id is of type ProcessInstance before calling the command

Example fix

// before
managementService.executeCommand(new SetProcessDefinitionVersionCmd(execution.getId(), 2));
// after
managementService.executeCommand(new SetProcessDefinitionVersionCmd(execution.getProcessInstanceId(), 2));
Defensive patterns

Strategy: type-guard

Validate before calling

ExecutionEntity e = executionEntityManager.findById(id);
boolean isRoot = e != null && e.isProcessInstanceType();

Type guard

boolean isProcessInstance(Execution e) { return e instanceof ProcessInstance; }

Try / catch

try { cmd.execute(ctx); } catch (FlowableIllegalArgumentException e) { /* retry with getProcessInstanceId() root id */ }

Prevention

When it happens

Trigger: Passing the id of a child/concurrent execution or execution-scoped id (e.g. from an Execution listener or execution query) into SetProcessDefinitionVersionCmd instead of the process instance's root id.

Common situations: Iterating RuntimeService.createExecutionQuery() results and treating every execution id as a process instance id; using execution.getId() from an activity context where getProcessInstanceId() was the correct value.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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