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()}'.

What it means

Thrown as FlowableIllegalArgumentException when the provided id resolves to an execution row that is a child (concurrent/scope) execution rather than the process instance itself. The command requires the root process-instance execution; a child execution id cannot be used to update instance-level data like the business key or name.

Source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/UpdateProcessInstanceCmd.java:55

    protected ProcessInstanceUpdateBuilderImpl builder;

    public UpdateProcessInstanceCmd(ProcessInstanceUpdateBuilderImpl builder) {
        this.builder = builder;
    }

    @Override
    public Void execute(CommandContext commandContext) {
        String processInstanceId = builder.getProcessInstanceId();
        if (processInstanceId == null || processInstanceId.isEmpty()) {
            throw new FlowableIllegalArgumentException("The process instance id is mandatory, but '" + processInstanceId + "' has been provided.");
        }

        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() + "'.");
        }

        if (builder.isBusinessKeySet()) {
            executionManager.updateProcessInstanceBusinessKey(processInstance, builder.getBusinessKey());
        }

        if (builder.isBusinessStatusSet()) {
            executionManager.updateProcessInstanceBusinessStatus(processInstance, builder.getBusinessStatus());
        }

        if (builder.isNameSet()) {
            processInstance.setName(builder.getName());
            ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
            processEngineConfiguration.getHistoryManager().recordProcessInstanceNameChange(processInstance, builder.getName());
        }

        if (builder.isDueDateSet()) {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Use the process instance id: get it via execution.getProcessInstanceId() from the child execution, then call the command with that id.
  2. In a delegate, use DelegateExecution.getProcessInstanceId() (or executionEntity.getProcessInstanceId()) instead of getId().
  3. Re-source ids from ProcessInstanceQuery rather than ExecutionQuery when the target is instance-level data.

Example fix

// before
String id = execution.getId(); // may be a child execution
runtimeService.setProcessInstanceName(id, name);
// after
String id = execution.getProcessInstanceId();
runtimeService.setProcessInstanceName(id, name);
Defensive patterns

Strategy: validation

Validate before calling

if (!processInstanceId.equals(executionQuery.executionId(executionId).singleResult().getProcessInstanceId())) { /* use getProcessInstanceId() instead */ }

Type guard

String toProcessInstanceId(Execution e) { return e.isProcessInstanceType() ? e.getId() : e.getProcessInstanceId(); }

Try / catch

try { runtimeService.setProcessInstanceName(id, name); } catch (FlowableIllegalArgumentException e) { LOG.error("id {} is a child execution", id, e); }

Prevention

When it happens

Trigger: Passing an execution id obtained from ExecutionQuery / execution.getExecutionId(), a child execution inside a parallel gateway or call-activity scope, or any non-root row of ACT_RU_EXECUTION to the update-process-instance command.

Common situations: Confusing Execution.getId() with ProcessInstance.getId(); using the 'executionId' variable from a delegate/task context in a multi-instance or concurrent branch; iteratively updating instances whose ids came from an executions query.

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/49b047f9f7c5a54f. Report an issue: GitHub.