{"record":{"id":"5c4e6b484d488d18","repo":"flowable/flowable-engine","slug":"could-not-complete-parent-process-instance-for-cal","errorCode":null,"errorMessage":"Could not complete parent process instance for call activity with process instance execution ","messagePattern":"Could not complete parent process instance for call activity with process instance execution ","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/persistence/entity/ExecutionEntityManagerImpl.java","lineNumber":473,"sourceCode":"            throw new FlowableObjectNotFoundException(\"No process instance found for id '\" + processInstanceId + \"'\", ProcessInstance.class);\n        }\n\n        deleteProcessInstanceCascade(processInstanceExecution, ProcessInstanceState.CANCELLED, deleteReason, cascade, directDeleteInDatabase);\n        \n        // Special care needed for a process instance of a call activity: the parent process instance needs to be triggered for completion\n        // This can't be added to the deleteProcessInstanceCascade method, as this will also trigger all child and/or multi-instance\n        // process instances for child call activities, which shouldn't happen.\n        if (processInstanceExecution.getSuperExecutionId() != null) {\n            ExecutionEntity superExecution = processInstanceExecution.getSuperExecution();\n            if (superExecution != null\n                    && superExecution.getCurrentFlowElement() instanceof FlowNode flowNode\n                    && flowNode.getBehavior() instanceof SubProcessActivityBehavior subProcessActivityBehavior) {\n                try {\n                    subProcessActivityBehavior.completing(superExecution, processInstanceExecution);\n                    superExecution.setSubProcessInstance(null);\n                    subProcessActivityBehavior.completed(superExecution);\n                } catch (Exception e) {\n                    throw new FlowableException(\"Could not complete parent process instance for call activity with process instance execution \" \n                                + processInstanceExecution, e);\n                }\n            }\n        }\n\n        if (engineConfiguration.getEndProcessInstanceInterceptor() != null) {\n            engineConfiguration.getEndProcessInstanceInterceptor().afterEndProcessInstance(processInstanceId, ProcessInstanceState.CANCELLED);\n        }\n    }\n\n    protected void deleteProcessInstanceCascade(ExecutionEntity execution, String state, String deleteReason, boolean deleteHistory, boolean directDeleteInDatabase) {\n\n        // fill default reason if none provided\n        if (deleteReason == null) {\n            deleteReason = DeleteReason.PROCESS_INSTANCE_DELETED;\n        }\n        getActivityInstanceEntityManager().deleteActivityInstancesByProcessInstanceId(execution.getId());\n","sourceCodeStart":455,"sourceCodeEnd":491,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/persistence/entity/ExecutionEntityManagerImpl.java#L455-L491","documentation":"While deleting a process instance that was started by a call activity, Flowable notifies the parent execution via SubProcessActivityBehavior.completing()/completed(). If any exception escapes those calls (e.g. the parent instance was concurrently deleted, its execution is in an invalid state, or a delegate/listener threw), it is wrapped in this FlowableException so the caller knows the parent process instance could not be completed.","triggerScenarios":"runtimeService.deleteProcessInstance on a child call-activity instance while the parent's execution is gone/corrupted or concurrently modified; a custom SubProcessActivityBehavior or execution/listener on the parent's call-activity throws; deleting child instances in parallel from multiple threads.","commonSituations":"Cleanup jobs cancelling subprocess instances while the parent flow concurrently ends; data copied between environments missing parent ACT_RU_EXECUTION rows; custom call-activity behaviors with bugs.","solutions":["Inspect the wrapped cause (e.getCause()) — the real fix depends on it (optimistic lock, missing parent, listener bug).","Avoid concurrent operations on parent/child instances: cancel the root process instance instead of individual call-activity children so both levels are handled atomically.","If parent data is missing (copied environments), repair ACT_RU_EXECUTION hierarchy rows or delete orphaned instances via cascade delete / SQL cleanup.","Fix any custom listener/behavior that throws inside completing()/completed()."],"exampleFix":"// before: cancelling a child call-activity instance directly\nruntimeService.deleteProcessInstance(childInstanceId, reason);\n\n// after: cancel at the root so parent completion is managed\nruntimeService.deleteProcessInstance(rootProcessInstanceId, reason);","handlingStrategy":"try-catch","validationCode":"// ensure parent is alive before cancelling the child\nlong parent = runtimeService.createProcessInstanceQuery()\n    .processInstanceId(parentInstanceId).count();\nif (parent == 0) {\n    // cancel root instead, or skip\n    return;\n}","typeGuard":null,"tryCatchPattern":"try {\n    runtimeService.deleteProcessInstance(childInstanceId, reason);\n} catch (FlowableException e) {\n    if (e.getMessage().startsWith(\"Could not complete parent process instance\")\n            && e.getCause() != null) {\n        log.warn(\"parent completion failed\", e.getCause());\n    } else { throw e; }\n}","preventionTips":["Cancel the root process instance rather than individual call-activity children.","Never operate on parent and child instances from parallel threads.","Always log/examine getCause() — this exception wraps the real failure.","Keep custom SubProcessActivityBehavior/listener code exception-safe."],"tags":["flowable","call-activity","subprocess","cancellation"],"backgroundTag":"internal-invariant-violation","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"}