flowable/flowable-engine · error · RuntimeException
Could not generate DI: boundaryEvent
Error message
Could not generate DI: boundaryEvent '${boundaryEvent.getId()}' has no attachedToRef What it means
BpmnAutoLayout generates BPMN DI (diagram interchange) coordinates. For a boundary event it must know which activity the event is attached to; if the boundary event has neither attachedToRefId nor attachedToRef, layout cannot place it and throws RuntimeException.
Solutions
- Set boundaryEvent.setAttachedToRefId("<activityId>") before calling layout()
- Or set boundaryEvent.setAttachedToRef(activity) with the target BaseElement
- Verify the attached-to activity id exists in the model (it must also be laid out)
Example fix
// before
BoundaryEvent be = new BoundaryEvent(); be.setId("be1");
process.addFlowElement(be);
// after
BoundaryEvent be = new BoundaryEvent(); be.setId("be1");
be.setAttachedToRefId("task1");
process.addFlowElement(be); Defensive patterns
Strategy: try-catch
Try / catch
try { layout.layout(); } catch (RuntimeException e) { if (e.getMessage().contains("has no attachedToRef")) { /* fix model */ } } Prevention
- Set attachedToRefId on every BoundaryEvent before layout
When it happens
Trigger: Programmatically building a BpmnModel with a BoundaryEvent and calling BpmnAutoLayout.layout() without setting attachedToRef/attachedToRefId on the boundary event.
Common situations: Code-generated models where the attachment link was skipped; models built from incomplete data; boundary events copied without their parent reference.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Activity needed for multi instance cannot bv found
- An error occurs converting output value as JSon
- ' ' is not valid boolean in mapException with errorCode=…
- BPMN XSD could not be found
- Can only complete BPMN external job with a BPMN error. Job…
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/2373255b9f7259f2.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-bpmn-layout/src/main/java/org/flowable/bpmn/BpmnAutoLayout.java:247
generatedVertices.put(flowElement.getId(), subProcessVertex);
}
protected void handleBoundaryEvents() {
for (BoundaryEvent boundaryEvent : boundaryEvents) {
mxGeometry geometry = new mxGeometry(0.8, 1.0, eventSize, eventSize);
geometry.setOffset(new mxPoint(-(eventSize / 2), -(eventSize / 2)));
geometry.setRelative(true);
mxCell boundaryPort = new mxCell(null, geometry, "shape=ellipse;perimeter=ellipsePerimeter");
boundaryPort.setId("boundary-event-" + boundaryEvent.getId());
boundaryPort.setVertex(true);
Object portParent = null;
if (boundaryEvent.getAttachedToRefId() != null) {
portParent = generatedVertices.get(boundaryEvent.getAttachedToRefId());
} else if (boundaryEvent.getAttachedToRef() != null) {
portParent = generatedVertices.get(boundaryEvent.getAttachedToRef().getId());
} else {
throw new RuntimeException("Could not generate DI: boundaryEvent '" + boundaryEvent.getId() + "' has no attachedToRef");
}
graph.addCell(boundaryPort, portParent);
generatedVertices.put(boundaryEvent.getId(), boundaryPort);
}
}
protected void handleSequenceFlow() {
Hashtable<String, Object> edgeStyle = new Hashtable<>();
edgeStyle.put(mxConstants.STYLE_ORTHOGONAL, true);
edgeStyle.put(mxConstants.STYLE_EDGE, mxEdgeStyle.ElbowConnector);
edgeStyle.put(mxConstants.STYLE_ENTRY_X, 0.0);
edgeStyle.put(mxConstants.STYLE_ENTRY_Y, 0.5);
graph.getStylesheet().putCellStyle(STYLE_SEQUENCEFLOW, edgeStyle);
Hashtable<String, Object> boundaryEdgeStyle = new Hashtable<>();
boundaryEdgeStyle.put(mxConstants.STYLE_EXIT_X, 0.5);View on GitHub (pinned to d6d39ce1c6)