flowable/flowable-engine · error · ActivitiException
Error while handling compensation event
Error message
Error while handling compensation event ${eventSubscription} What it means
Thrown by CompensationEventHandler.handleEvent when any exception occurs while executing a compensation handler for a compensation event subscription. The handler resolves the compensation handler activity, moves a compensating execution to it, and performs ACTIVITY_START; any failure inside that block (missing activity, process errors) is wrapped in this ActivitiException with the original exception as cause. Always inspect the cause to find the root problem.
Solutions
- Inspect the cause chain of the ActivitiException to find the real failure inside the compensation handler execution.
- Verify the event subscription's activity id still exists in the deployed process definition; redeploy a consistent model and clear stale subscriptions.
- Fix the underlying bug in the compensation handler code (service task/delegate) that threw during ACTIVITY_START.
- Re-run the failed compensation from a clean process state after correcting the model; if needed delete the stale EventSubscription row.
Example fix
// before: opaque wrap, root cause hidden
throw new ActivitiException("Error while handling compensation event " + eventSubscription, e);
// after: log cause explicitly and rethrow with context
try {
compensatingExecution.performOperation(AtomicOperation.ACTIVITY_START);
} catch (Exception e) {
LOGGER.warn("Compensation handler {} failed", compensationHandler != null ? compensationHandler.getId() : "unknown", e);
throw new ActivitiException("Error while handling compensation event " + eventSubscription, e);
} Defensive patterns
Strategy: try-catch
Validate before calling
// before signaling compensation, ensure the subscription and handler activity exist
EventSubscription sub = runtimeService.createEventSubscriptionQuery()
.eventType("compensate").singleResult();
if (sub == null) throw new IllegalStateException("No compensation subscription"); Try / catch
try {
// trigger compensation path
} catch (org.activiti.engine.ActivitiException e) {
LOGGER.error("Compensation failed: {}", e.getMessage(), e.getCause());
throw new CompensationFailedException(e.getCause());
} Prevention
- Always log the full cause chain; this error only wraps the real failure.
- Keep compensation handler activity ids stable across process model versions.
- Test compensation paths in CI with models that mimic production BPMN.
- Avoid deleting deployments that still have live event subscriptions.
When it happens
Trigger: A compensation event is thrown (end/intermediate compensation event or process-level compensation) and handleEvent fails while creating/executing the compensating execution, e.g. the compensation handler activity cannot be resolved or throws during ACTIVITY_START.
Common situations: BPMN models with boundary compensation handlers whose target activity was changed or removed; engine data inconsistency where the event subscription references a stale activity; exceptions inside service tasks participating in compensation; upgrading flows where the process definition was redeployed with a different model while subscriptions persisted in the DB.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Compensating execution not set for " + eventSubscription
- No outgoing sequence flow of the inclusive gateway
- Not supported to signal this execution
- Cannot start process instance. Process model (id = " +…
- Cannot trigger : no current flow element found. Check the…
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/77d49ddcf9a8300f.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/event/CompensationEventHandler.java:85
if (commandContext.getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
commandContext.getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
ActivitiEventBuilder.createActivityEvent(FlowableEngineEventType.ACTIVITY_COMPENSATE,
compensationHandler.getId(),
(String) compensationHandler.getProperty("name"),
compensatingExecution.getId(),
compensatingExecution.getProcessInstanceId(),
compensatingExecution.getProcessDefinitionId(),
(String) compensatingExecution.getActivity().getProperties().get("type"),
compensatingExecution.getActivity().getActivityBehavior().getClass().getCanonicalName()),
EngineConfigurationConstants.KEY_PROCESS_ENGINE_CONFIG);
}
compensatingExecution.setActivity(compensationHandler);
// executing the atomic operation makes sure activity start events are fired
compensatingExecution.performOperation(AtomicOperation.ACTIVITY_START);
} catch (Exception e) {
throw new ActivitiException("Error while handling compensation event " + eventSubscription, e);
}
}
}
}
View on GitHub (pinned to d6d39ce1c6)