{"record":{"id":"99ebb5be09e5d077","repo":"flowable/flowable-engine","slug":"process-instance-with-id-processinstanceid-is","errorCode":null,"errorMessage":"Process instance with id '${processInstanceId}' is already active.","messagePattern":"Process instance with id '(.+?)' is already active\\.","errorType":"exception","errorClass":"FlowableConflictException","httpStatus":409,"severity":"warning","filePath":"modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/process/ProcessInstanceResource.java","lineNumber":322,"sourceCode":"            }\n            DynamicEmbeddedSubProcessBuilder subProcessBuilder = new DynamicEmbeddedSubProcessBuilder();\n            subProcessBuilder.id(injectActivityRequest.getId())\n                .processDefinitionId(injectActivityRequest.getProcessDefinitionId());\n            \n            if (injectActivityRequest.getTaskId() != null) {\n                dynamicBpmnService.injectParallelEmbeddedSubProcess(injectActivityRequest.getTaskId(), subProcessBuilder);\n            } else {\n                dynamicBpmnService.injectEmbeddedSubProcessInProcessInstance(processInstanceId, subProcessBuilder);\n            }\n        \n        } else {\n            throw new FlowableIllegalArgumentException(\"injection type is not supported \" + injectActivityRequest.getInjectionType());\n        }\n    }\n\n    protected ProcessInstanceResponse activateProcessInstance(ProcessInstance processInstance) {\n        if (!processInstance.isSuspended()) {\n            throw new FlowableConflictException(\"Process instance with id '\" + processInstance.getId() + \"' is already active.\");\n        }\n        runtimeService.activateProcessInstanceById(processInstance.getId());\n\n        ProcessInstanceResponse response = restResponseFactory.createProcessInstanceResponse(processInstance);\n\n        // No need to re-fetch the instance, just alter the suspended state of the result-object\n        response.setSuspended(false);\n        return response;\n    }\n\n    protected ProcessInstanceResponse suspendProcessInstance(ProcessInstance processInstance) {\n        if (processInstance.isSuspended()) {\n            throw new FlowableConflictException(\"Process instance with id '\" + processInstance.getId() + \"' is already suspended.\");\n        }\n        runtimeService.suspendProcessInstanceById(processInstance.getId());\n\n        ProcessInstanceResponse response = restResponseFactory.createProcessInstanceResponse(processInstance);\n","sourceCodeStart":304,"sourceCodeEnd":340,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/process/ProcessInstanceResource.java#L304-L340","documentation":"Flowable REST throws FlowableConflictException when activating a process instance that is not suspended. The activate action (action=activate on PUT of the process instance) only makes sense on a suspended instance; otherwise the operation would be a no-op conflict.","triggerScenarios":"PUT /runtime/process-instances/{id} with {\"action\":\"activate\"} while the instance is running (suspended == false); racing activation from two clients.","commonSituations":"Scheduled resume job re-fires after the instance was already activated; retry logic re-sends an activate action without checking state; activation of instances selected by an overly broad query.","solutions":["Check GET /runtime/process-instances/{id} for suspended==true before sending action=activate.","Treat HTTP 409 from this call as success in idempotent job code.","Scope suspension/activation queries to only the affected instances."],"exampleFix":"// before\nput(pid, {\"action\":\"activate\"}); // 409 if already active\n// after\nconst inst = get(pid); if (inst.suspended) put(pid, {\"action\":\"activate\"});","handlingStrategy":"try-catch","validationCode":"const inst = await get(`/runtime/process-instances/${pid}`); if (inst.suspended) await put(pid, {action:'activate'});","typeGuard":null,"tryCatchPattern":"try { put(pid, {action:'activate'}); } catch (e) { if (e.status === 409) return; throw e; }","preventionTips":["Check suspended state before activate","Treat 409 as idempotent success","Avoid re-firing activation jobs"],"tags":["rest-api","conflict","state-transition"],"backgroundTag":"invalid-state-transition","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"}