{"record":{"id":"b3081f71dc90fc09","repo":"flowable/flowable-engine","slug":"a-process-instance-id-is-required-but-the-provide","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":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/ProcessInstanceClaimCmd.java","lineNumber":60,"sourceCode":"\n    public ProcessInstanceClaimCmd(String processInstanceId, String userId) {\n        if (processInstanceId == null || processInstanceId.isEmpty()) {\n            throw new FlowableIllegalArgumentException(\"The process instance id is mandatory, but '\" + processInstanceId + \"' has been provided.\");\n        }\n\n        this.processInstanceId = processInstanceId;\n        this.userId = userId;\n    }\n\n    @Override\n    public Void execute(CommandContext commandContext) {\n        ExecutionEntityManager executionManager = CommandContextUtil.getExecutionEntityManager(commandContext);\n        ExecutionEntity processInstance = executionManager.findById(processInstanceId);\n        if (processInstance == null) {\n            throw new FlowableObjectNotFoundException(\"No process instance found for id = '\" + processInstanceId + \"'.\", ProcessInstance.class);\n\n        } else if (!processInstance.isProcessInstanceType()) {\n            throw new FlowableIllegalArgumentException(\"A process instance id is required, but the provided id \" + \"'\" + processInstanceId + \"' \" + \"points to a child execution of process instance \" + \"'\"\n                    + processInstance.getProcessInstanceId() + \"'. \" + \"Please invoke the \" + getClass().getSimpleName() + \" with a root execution id.\");\n        }\n\n        ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);\n        if (userId != null) {\n            List<IdentityLinkEntity> identityLinks = processEngineConfiguration.getIdentityLinkServiceConfiguration()\n                    .getIdentityLinkService().findIdentityLinksByProcessInstanceId(processInstanceId);\n            for (IdentityLinkEntity identityLink : identityLinks) {\n                if (IdentityLinkType.ASSIGNEE.equals(identityLink.getType())) {\n                    throw new FlowableException(\"Process instance '\" + processInstanceId + \"' is already claimed.\");\n                }\n            }\n\n            IdentityLinkUtil.createProcessInstanceIdentityLink(processInstance, userId, null, IdentityLinkType.ASSIGNEE);\n\n            executionManager.updateProcessInstanceClaimTime(processInstance,\n                    processEngineConfiguration.getClock().getCurrentTime(), userId);\n","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/ProcessInstanceClaimCmd.java#L42-L78","documentation":"ProcessInstanceClaimCmd requires the id of the ROOT execution (the process instance itself). If the id resolves to a child/concurrent execution (isProcessInstanceType() is false), it throws FlowableIllegalArgumentException telling the caller to pass a root execution id instead.","triggerScenarios":"Executing ProcessInstanceClaimCmd with an execution id obtained from ExecutionQuery results for a child scope (e.g. a concurrent or event-scope execution) rather than the process instance id.","commonSituations":"Iterating RuntimeService.createExecutionQuery() results and using each execution's id; confusing executionId with processInstanceId in process variable/callback payloads; nested/async-continuation processes producing extra child executions.","solutions":["Pass the processInstanceId (execution.getId() where isProcessInstanceType() is true / execution.getProcessInstanceId()) instead of a child execution id.","When iterating executions, filter with executionQuery.processInstanceId(pid) and take the root, or check ProcessInstance type before selecting the id.","Catch FlowableIllegalArgumentException; if the message mentions a parent process instance id, extract it and retry the claim on the root id.","Store and propagate processInstanceId (not executionId) wherever claim/unclaim operations will be needed."],"exampleFix":"// before\nExecution exec = runtimeService.createExecutionQuery().executionId(childExecutionId).singleResult();\nmanagementService.executeCommand(new ProcessInstanceClaimCmd(childExecutionId, userId));\n// after\nExecution exec = runtimeService.createExecutionQuery().executionId(childExecutionId).singleResult();\nString rootId = exec.getProcessInstanceId(); // root execution id\nmanagementService.executeCommand(new ProcessInstanceClaimCmd(rootId, userId));","handlingStrategy":"validation","validationCode":"Execution exec = runtimeService.createExecutionQuery().executionId(id).singleResult();\nif (exec == null || !exec.isProcessInstanceType()) { throw new IllegalArgumentException(\"A root process instance id is required\"); }","typeGuard":"boolean isRootProcessInstanceId(String id) {\n    Execution e = runtimeService.createExecutionQuery().executionId(id).singleResult();\n    return e != null && e.isProcessInstanceType();\n}","tryCatchPattern":"try {\n    managementService.executeCommand(new ProcessInstanceClaimCmd(id, userId));\n} catch (FlowableIllegalArgumentException e) {\n    if (e.getMessage().contains(\"child execution\")) {\n        // retry with the parent process instance id reported in the message\n    } else { throw e; }\n}","preventionTips":["Always store processInstanceId (not executionId) for instance-level operations.","When iterating ExecutionQuery results, filter to the root execution.","Name API fields explicitly (processInstanceId vs executionId) to avoid mixups.","Add integration tests with multi-execution (async/concurrent) processes."],"tags":["flowable","invalid-argument","process-instance","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-14T11:17:12.474Z"}