flowable/flowable-engine · warning
compensation boundary catch must be connected to element wit
Error message
compensation boundary catch must be connected to element with isForCompensation=true
What it means
createAssociation() warns when an association connects a compensation boundary catch to an activity whose isForCompensation flag is not true. Compensation handlers must be marked isForCompensation="true"; otherwise the engine refuses to register it as the compensation handler and the association is ignored.
Source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/bpmn/parser/handler/AbstractBpmnParseHandler.java:203
// connected to a text annotation so skipping it
return;
}
ActivityImpl sourceActivity = parentScope.findActivity(association.getSourceRef());
ActivityImpl targetActivity = parentScope.findActivity(association.getTargetRef());
// an association may reference elements that are not parsed as activities (like for instance
// text annotations so do not throw an exception if sourceActivity or targetActivity are null)
// However, we make sure they reference 'something':
if (sourceActivity == null) {
// bpmnModel.addProblem("Invalid reference sourceRef '" + association.getSourceRef() + "' of association element ", association.getId());
} else if (targetActivity == null) {
// bpmnModel.addProblem("Invalid reference targetRef '" + association.getTargetRef() + "' of association element ", association.getId());
} else {
if (sourceActivity.getProperty("type").equals("compensationBoundaryCatch")) {
Object isForCompensation = targetActivity.getProperty(PROPERTYNAME_IS_FOR_COMPENSATION);
if (isForCompensation == null || !(Boolean) isForCompensation) {
LOGGER.warn("compensation boundary catch must be connected to element with isForCompensation=true");
} else {
ActivityImpl compensatedActivity = sourceActivity.getParentActivity();
compensatedActivity.setProperty(BpmnParse.PROPERTYNAME_COMPENSATION_HANDLER_ID, targetActivity.getId());
}
}
}
}
protected Map<String, Object> processDataObjects(BpmnParse bpmnParse, Collection<ValuedDataObject> dataObjects, ScopeImpl scope) {
Map<String, Object> variablesMap = new HashMap<>();
// convert data objects to process variables
if (dataObjects != null) {
for (ValuedDataObject dataObject : dataObjects) {
variablesMap.put(dataObject.getName(), dataObject.getValue());
}
}
return variablesMap;
}View on GitHub (pinned to d6d39ce1c6)
Solutions
- Set isForCompensation="true" on the activity targeted by the compensation association
- Verify the association direction: source should be the compensation boundary catch, target the compensation handler
- Re-model the compensation pattern so the handler activity is a dedicated compensation task
Example fix
// before <serviceTask id="undoTask"/> <association sourceRef="compCatch" targetRef="undoTask"/> // after <serviceTask id="undoTask" isForCompensation="true"/> <association sourceRef="compCatch" targetRef="undoTask"/>
Defensive patterns
Strategy: validation
Validate before calling
// Compensation targets must be marked isForCompensation
for (Association a : process.getArtifactsOfType(Association.class)) {
BaseElement target = process.getFlowElement(a.getTargetRef());
if (isCompensationBoundaryCatch(a.getSourceRef()) && !Boolean.TRUE.equals(isForCompensation(target)))
throw new IllegalArgumentException("Compensation handler must set isForCompensation=true: " + a.getTargetRef());
} Prevention
- Always set isForCompensation="true" on compensation handler activities
- Use standard compensation modeling patterns from the docs
When it happens
Trigger: An association whose source is a compensation boundary catch (type "compensationBoundaryCatch") targets an activity lacking PROPERTYNAME_IS_FOR_COMPENSATION=true; logged in AbstractBpmnParseHandler.createAssociation() called from processArtifacts.
Common situations: Modeling a compensation handler without setting isForCompensation=true on the target task/subprocess; importing BPMN from other tools that omit the attribute.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Parent activity for boundary compensation event could not be
- Process model for ${executionEntity} could not be found
- Compensation activity could not be found (or it is missing '
- Process model (id = ${processDefinitionId}) could not be fou
- Compensating execution not set for " + eventSubscription
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/b8d17e91643bbc63.
Report an issue: GitHub.