flowable/flowable-engine · error · ActivitiException

Error while completing sub process of execution

Error message

Error while completing sub process of execution ${execution}

What it means

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.

Solutions

  1. Inspect the wrapped cause of the ActivitiException to find the checked exception from completing()
  2. Fix the failing logic inside SubProcessActivityBehavior.completing()
  3. Convert expected checked exceptions to RuntimeExceptions inside the behavior with a clear message
  4. Ensure the sub-process execution state (variables, scopes) is valid before completion

Example fix

// before
public void completing(DelegateExecution superExec, DelegateExecution subExec) throws Exception {
  files.commit(subExec); // throws IOException
}
// after
public void completing(DelegateExecution superExec, DelegateExecution subExec) {
  try { files.commit(subExec); }
  catch (IOException e) { throw new ActivitiException("subprocess commit failed", e); }
}
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-deployment check: the sub-process behavior is registered and instantiable
Class.forName("com.example.MySubProcessBehavior").getDeclaredConstructor().newInstance();

Try / catch

try {
  runtimeService.startProcessInstanceByKey(key);
} catch (ActivitiException e) {
  log.error("subprocess completing failed", e.getCause());
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/49803ee1773b07f0. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/pvm/runtime/AtomicOperationProcessEnd.java:56

    }

    @Override
    protected void eventNotificationsCompleted(InterpretableExecution execution) {
        InterpretableExecution superExecution = execution.getSuperExecution();
        SubProcessActivityBehavior subProcessActivityBehavior = null;

        // copy variables before destroying the ended sub process instance
        if (superExecution != null) {
            ActivityImpl activity = (ActivityImpl) superExecution.getActivity();
            subProcessActivityBehavior = (SubProcessActivityBehavior) activity.getActivityBehavior();
            try {
                subProcessActivityBehavior.completing(superExecution, execution);
            } catch (RuntimeException e) {
                LOGGER.error("Error while completing sub process of execution {}", execution, e);
                throw e;
            } catch (Exception e) {
                LOGGER.error("Error while completing sub process of execution {}", execution, e);
                throw new ActivitiException("Error while completing sub process of execution " + execution, e);
            }
        }

        execution.destroy();
        execution.remove();

        // and trigger execution afterwards
        if (superExecution != null) {
            superExecution.setSubProcessInstance(null);
            try {
                subProcessActivityBehavior.completed(superExecution);
            } catch (RuntimeException e) {
                LOGGER.error("Error while completing sub process of execution {}", execution, e);
                throw e;
            } catch (Exception e) {
                LOGGER.error("Error while completing sub process of execution {}", execution, e);
                throw new ActivitiException("Error while completing sub process of execution " + execution, e);
            }

View on GitHub (pinned to d6d39ce1c6)