{"record":{"id":"49803ee1773b07f0","repo":"flowable/flowable-engine","slug":"error-while-completing-sub-process-of-execution-49803e","errorCode":null,"errorMessage":"Error while completing sub process of execution ${execution}","messagePattern":"Error while completing sub process of execution (.+?)","errorType":"exception","errorClass":"ActivitiException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/pvm/runtime/AtomicOperationProcessEnd.java","lineNumber":56,"sourceCode":"    }\n\n    @Override\n    protected void eventNotificationsCompleted(InterpretableExecution execution) {\n        InterpretableExecution superExecution = execution.getSuperExecution();\n        SubProcessActivityBehavior subProcessActivityBehavior = null;\n\n        // copy variables before destroying the ended sub process instance\n        if (superExecution != null) {\n            ActivityImpl activity = (ActivityImpl) superExecution.getActivity();\n            subProcessActivityBehavior = (SubProcessActivityBehavior) activity.getActivityBehavior();\n            try {\n                subProcessActivityBehavior.completing(superExecution, execution);\n            } catch (RuntimeException e) {\n                LOGGER.error(\"Error while completing sub process of execution {}\", execution, e);\n                throw e;\n            } catch (Exception e) {\n                LOGGER.error(\"Error while completing sub process of execution {}\", execution, e);\n                throw new ActivitiException(\"Error while completing sub process of execution \" + execution, e);\n            }\n        }\n\n        execution.destroy();\n        execution.remove();\n\n        // and trigger execution afterwards\n        if (superExecution != null) {\n            superExecution.setSubProcessInstance(null);\n            try {\n                subProcessActivityBehavior.completed(superExecution);\n            } catch (RuntimeException e) {\n                LOGGER.error(\"Error while completing sub process of execution {}\", execution, e);\n                throw e;\n            } catch (Exception e) {\n                LOGGER.error(\"Error while completing sub process of execution {}\", execution, e);\n                throw new ActivitiException(\"Error while completing sub process of execution \" + execution, e);\n            }","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/pvm/runtime/AtomicOperationProcessEnd.java#L38-L74","documentation":"Thrown when a SubProcessActivityBehavior's completing(superExecution, execution) callback throws a checked Exception while the embedded sub-process execution is being ended. The engine logs the error and rethrows an ActivitiException wrapping it. It signals that leaving the sub-process boundary back into the parent process failed.","triggerScenarios":"A custom SubProcessActivityBehavior.completing() implementation throwing a checked Exception during eventNotificationsCompleted of AtomicOperationProcessEnd; also any delegate/listener invoked as part of completing the sub-process scope that throws a checked exception.","commonSituations":"Custom embedded sub-process behaviors (e.g. BPMN subprocess adapters) doing cleanup that fails; version-migrated custom behaviors whose callback signatures changed; resource cleanup errors when leaving a call-activity-like scope.","solutions":["Inspect the wrapped cause of the ActivitiException to find the checked exception from completing()","Fix the failing logic inside SubProcessActivityBehavior.completing()","Convert expected checked exceptions to RuntimeExceptions inside the behavior with a clear message","Ensure the sub-process execution state (variables, scopes) is valid before completion"],"exampleFix":"// before\npublic void completing(DelegateExecution superExec, DelegateExecution subExec) throws Exception {\n  files.commit(subExec); // throws IOException\n}\n// after\npublic void completing(DelegateExecution superExec, DelegateExecution subExec) {\n  try { files.commit(subExec); }\n  catch (IOException e) { throw new ActivitiException(\"subprocess commit failed\", e); }\n}","handlingStrategy":"try-catch","validationCode":"// pre-deployment check: the sub-process behavior is registered and instantiable\nClass.forName(\"com.example.MySubProcessBehavior\").getDeclaredConstructor().newInstance();","typeGuard":null,"tryCatchPattern":"try {\n  runtimeService.startProcessInstanceByKey(key);\n} catch (ActivitiException e) {\n  log.error(\"subprocess completing failed\", e.getCause());\n}","preventionTips":["Never let checked exceptions escape SubProcessActivityBehavior callbacks","Test sub-process exit paths (all boundary events and end states)","Avoid depending on child execution state during completing/completed"],"tags":["process-engine","subprocess","wrapped-exception"],"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"}