{"record":{"id":"530f9454f22edf28","repo":"flowable/flowable-engine","slug":"a-process-instance-id-is-required-but-the-provide-530f94","errorCode":null,"errorMessage":"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.","messagePattern":"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\\.","errorType":"exception","errorClass":"ActivitiIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/SetProcessDefinitionVersionCmd.java","lineNumber":82,"sourceCode":"            throw new ActivitiIllegalArgumentException(\"The process definition version is mandatory, but 'null' has been provided.\");\n        }\n        if (processDefinitionVersion < 1) {\n            throw new ActivitiIllegalArgumentException(\"The process definition version must be positive, but '\" + processDefinitionVersion + \"' has been provided.\");\n        }\n        this.processInstanceId = processInstanceId;\n        this.processDefinitionVersion = processDefinitionVersion;\n    }\n\n    @Override\n    public Void execute(CommandContext commandContext) {\n        // check that the new process definition is just another version of the same\n        // process definition that the process instance is using\n        ExecutionEntityManager executionManager = commandContext.getExecutionEntityManager();\n        ExecutionEntity processInstance = executionManager.findExecutionById(processInstanceId);\n        if (processInstance == null) {\n            throw new ActivitiObjectNotFoundException(\"No process instance found for id = '\" + processInstanceId + \"'.\", ProcessInstance.class);\n        } else if (!processInstance.isProcessInstanceType()) {\n            throw new ActivitiIllegalArgumentException(\n                    \"A process instance id is required, but the provided id \" +\n                            \"'\" + processInstanceId + \"' \" +\n                            \"points to a child execution of process instance \" +\n                            \"'\" + processInstance.getProcessInstanceId() + \"'. \" +\n                            \"Please invoke the \" + getClass().getSimpleName() + \" with a root execution id.\");\n        }\n        ProcessDefinitionImpl currentProcessDefinitionImpl = processInstance.getProcessDefinition();\n\n        DeploymentManager deploymentCache = commandContext\n                .getProcessEngineConfiguration()\n                .getDeploymentManager();\n        ProcessDefinition currentProcessDefinition = null;\n        if (currentProcessDefinitionImpl instanceof ProcessDefinitionEntity) {\n            currentProcessDefinition = (ProcessDefinitionEntity) currentProcessDefinitionImpl;\n        } else {\n            currentProcessDefinition = deploymentCache.findDeployedProcessDefinitionById(currentProcessDefinitionImpl.getId());\n        }\n","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/SetProcessDefinitionVersionCmd.java#L64-L100","documentation":"findExecutionById can return a child (concurrent or scope) execution rather than the root. Because the command must operate on the process instance as a whole, it checks isProcessInstanceType() and throws ActivitiIllegalArgumentException when the id points to a child execution, telling the caller to use the root execution id.","triggerScenarios":"Passing an execution id (e.g. from an ExecutionQuery, a task's executionId, or an event listener on a concurrent branch) into setProcessDefinitionVersion instead of the process instance id.","commonSituations":"Code that stores executionId from a DelegateExecution in a parallel/multi-instance branch and later uses it as an instance id; migration scripts iterating executions rather than process instances.","solutions":["Use processInstance.getProcessInstanceId() (available on the child execution) as the id — that is always the root.","Query with runtimeService.createProcessInstanceQuery().processInstanceId(...) instead of createExecutionQuery() to obtain root ids.","In listeners, use delegateExecution.getProcessInstanceId(), not getExecutionId()."],"exampleFix":"// before\nruntimeService.setProcessDefinitionVersion(execution.getId(), newVersion); // child execution\n// after\nruntimeService.setProcessDefinitionVersion(execution.getProcessInstanceId(), newVersion);","handlingStrategy":"validation","validationCode":"String rootId = execution.isProcessInstanceType() ? execution.getId() : execution.getProcessInstanceId();","typeGuard":"boolean isRootExecution(Execution e) { return e.isProcessInstanceType(); }","tryCatchPattern":"try {\n    runtimeService.setProcessDefinitionVersion(pid, version);\n} catch (org.activiti.engine.ActivitiIllegalArgumentException e) {\n    // pid was a child execution; resolve root and retry\n}","preventionTips":["Use getProcessInstanceId(), never getExecutionId(), when an instance id is needed","Query ProcessInstanceQuery instead of ExecutionQuery for instance-level operations"],"tags":["java","flowable","argument-validation","execution-id"],"backgroundTag":"invalid-argument-value","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}