BPMN Validator Rules
The LucidFlow BPMN Validator ships 113 rules covering structure, flow, events, gateways, semantic references, and BPMN DI consistency. 5 of them have deep documentation with examples and fix patterns; the rest are self-explaining from their summary line and OMG spec reference.
Structure (19)
- Error
missingRequiredAttributeXSD-required attributes (sequenceFlow / messageFlow refs, boundaryEvent.attachedToRef, dataObjectReference.dataObjectRef) must be present. - Error
noDefinitionsDocument root must be <definitions>.OMG §8 - Error
noBpmnNamespaceRoot must declare the BPMN 2.0 namespace.OMG §8 - Error
noProcessDocument must contain at least one <process>. - Error
duplicateIdAll id attributes must be unique across the document.In-depth - Info
processName<process> without a name is harder to identify in tooling. - Warning
invalidIdFormatIDs must be valid XML NCNames (letter/underscore start, no colons). - Error
xsdBooleanAttributexs:boolean attributes must use exactly "true" / "false" / "1" / "0". - Error
adHocSubProcessNoStartEndEvents<adHocSubProcess> must not contain start events or end events.OMG §10.2.5 - Error
callActivityMissingCalledElement<callActivity> must declare a calledElement attribute — the engine has nothing to call without it.OMG §10.2.7 - Error
loopCharacteristicsOnGatewayLoop characteristics on a Gateway is XSD-invalid — loops belong to Activities only. - Error
multiInstanceLoopInvalidLoop characteristics with non-positive cardinality, no cardinality source, or no termination condition cannot drive a loop.OMG §10.2.6 / §10.2.7 - Error
associationDirectionEnum<association> associationDirection must be one of "None" / "One" / "Both". - Warning
serviceTaskImplementation<serviceTask> / <businessRuleTask> should declare an implementation hook (standard implementation attribute, Camunda delegate / class / expression / decisionRef, or Zeebe taskDefinition).OMG §10.3.3 - Error
scriptTaskMissingFormat<scriptTask> must declare a scriptFormat attribute (error); a missing <script> body is a separate warning.OMG §10.3.6 - Error
callActivityCalledElement<callActivity> must declare calledElement (error on missing); unresolved local lookup is a warning since cross-document calls are legal.OMG §10.2.7 - Warning
userTaskNoAssignee<userTask> with no humanPerformer / potentialOwner / camunda:assignee / camunda:candidateGroups / camunda:candidateUsers / flowable:assignee — task may be unclaimed at runtime.OMG §10.3.4 - Info
unknownElementBPMN-namespaced element not in the curated allow-list — probably a vendor extension. - Info
multipleProcessesDocument declares 2+ <process> elements (collaboration shape).
Flow & connectivity (11)
- Error
invalidFlowRefSequence flow sourceRef / targetRef must resolve to an existing node.In-depth - Warning
orphanNodeFlow node has no incoming and no outgoing flow in its scope (excluding adhoc and wired compensation handlers). - Warning
unreachableFromStartNon-orphan flow node not reachable from any start event in its scope. - Warning
cannotReachEndNon-orphan flow node unable to reach any end event in its scope. - Warning
infiniteLoopCycle (multi-node SCC) with no exit edge to an end event — deadlock loop. - Warning
wfNetSoundnessFormal soundness analysis via BPMN→WF-net translation (option to complete, proper completion, no dead transitions).OMG Aalst 1997 / Dijkman 2008 - Error
incomingOutgoingChildIntegrity<incoming> / <outgoing> child of a flow node must name an existing <sequenceFlow> in the same scope.OMG §8.3.1 - Warning
implicitMultiMergeNon-gateway flow node with 2+ incoming sequence flows — implicit merge has ambiguous semantics.OMG §13.3.3 - Warning
improperCompletionParallel-split branches reach plain end events without synchronizing — firing one leaves another branch with an active token.OMG §13.4.2 - Warning
selfLoopOnFlowNodeFlow node has a self-loop sequence flow — pure self-loop is a deadlock; mixed self-loop is a livelock risk. - Error
sequenceFlowCrossesBoundarySequence flow endpoints must live in the same containment scope — use a message flow to cross pools.OMG §7.3.1
Events (37)
- Warning
noStartEventExecutable top-level <process> should have at least one start event.In-depth - Warning
noEndEventExecutable top-level <process> should have at least one end event. - Error
startEventWithIncomingStart events must not have an incoming sequence flow.OMG §10.4.2 - Error
endEventWithOutgoingEnd events must not have an outgoing sequence flow.OMG §10.4.3 - Error
boundaryAttachBoundary event must reference an existing activity through attachedToRef. - Warning
emptyTimerEventDefinitiontimerEventDefinition needs at least one of timeDate / timeDuration / timeCycle.OMG §10.5.4 - Error
eventSubProcessMisconfiguredEvent sub-process / regular sub-process mismatch on triggeredByEvent vs start-event trigger. - Warning
eventSubProcessMissingIsInterruptingEvent sub-process start event omits isInterrupting attribute — implicit default invites confusion between interrupting and non-interrupting handlers.OMG §10.4.2 - Error
cancelEventOnlyInTransactionCancel end / boundary event valid only on <transaction>.OMG §10.5.6 - Warning
terminateEventScopeTerminate end event inside a subprocess kills the whole process instance — usually a modeling mistake. - Error
messageFlowMissingEndpointsMessage flow must declare both sourceRef and targetRef (deferred to the pre-pass when absent).OMG §9.3.1 - Error
messageFlowSelfLoopMessage flow endpoints must be distinct — self-loops are vacuous (the message would not cross a pool boundary).OMG §9.3.1 - Error
messageFlowEndpointTypeMessage flow sourceRef / targetRef must point to a participant or InteractionNode, not a sequenceFlow.OMG §9.3.1 - Error
messageFlowSameProcessMessage flow endpoints must live in different processes (pools); use a sequence flow for intra-process links. - Info
messageFlowMissingMessageRefMessage flow without messageRef — engines often drop or reject the flow on import because payload semantics are undefined. - Info
compensationBoundaryRequiresAssociationCompensation boundary event lacks an <association> to a handler activity — handler never fires.OMG §10.5.5 - Info
nonInterruptingBoundaryLoopbackNon-interrupting boundary event loops directly back to its attached activity — unbounded re-entrancy risk.OMG §10.5.7 - Warning
subProcessNoStartEventEmbedded <subProcess> / <transaction> has no inner start event — the subprocess has no entry point.OMG §10.2.4 - Warning
multipleNoneStartEventsProcess declares 2+ None start events at top level — starter ambiguity; use typed starts to disambiguate. - Warning
compensateBoundaryCancelActivityCompensation boundary event declares cancelActivity="true" — compensate boundaries are non-interrupting by definition.OMG §10.5.5 - Error
interruptingBoundaryCancelActivityError / cancel boundary events are always interrupting — cancelActivity="false" contradicts §10.5.2 / §10.5.6.OMG §10.5.2 - Warning
linkEventPairingLink throw / catch events must pair by name within the same process — orphan throws and orphan catches drop tokens silently.OMG §10.5.4 - Error
invalidTimerDuration<timeDuration> / <timeCycle> must be a valid ISO 8601 duration.OMG §10.5.4 - Error
invalidTimerDate<timeDate> must be a valid ISO 8601 dateTime.OMG §10.5.4 - Info
messageTaskMissingMessageRef<sendTask> / <receiveTask> without messageRef — engines often drop or reject the task on import.OMG §10.3.5 - Warning
multipleEventDefinitionsOnEventEvent combines multiple event definitions — engine semantics is engine-defined; split into separate events. - Warning
typedEventPairingSignal / error / escalation throws must have matching catches by ref attribute (and vice versa).OMG §10.5.4 - Warning
compensateThrowTargetValidityCompensate throw activityRef must point to an existing activity with isForCompensation="true".OMG §10.5.5 - Warning
boundaryKillInAndBranchParallel-join branch contains an activity guarded by an interrupting boundary — the branch can disappear and deadlock the join. - Warning
multiHopNonInterruptingLoopbackNon-interrupting boundary loops back to its attached activity through a multi-hop path — unbounded multi-instance fan-out.OMG §10.5.7 - Error
linkEventPairingByContainerLink throw and catch events must pair within the same immediate container (process / subProcess / transaction / adHocSubProcess); N→1 valid, orphans and 1→N ambiguity errored.OMG §10.4.6 - Error
errorEndEventScopeError end event at the root of a <process> has no enclosing activity to propagate the error to.OMG §10.5.4 - Warning
timerExpressionSyntaxtimeDate / timeDuration must match ISO 8601 lexical forms; timeCycle accepts ISO 8601 repeating intervals or cron expressions.OMG §10.5.4 - Warning
conditionalEventEmptyExpression<conditionalEventDefinition> must declare a non-empty <conditionExpression> child — empty expressions have engine-defined semantics.OMG §10.5.4 - Warning
terminateEndEventSubprocessScopeTerminate end event inside a subprocess terminates only the subprocess, not the root process — frequent modeling confusion.OMG §10.5.4 - Error
messageTaskMissingRef<sendTask> / <receiveTask> must reference a <message> via messageRef (error on missing, warning on unresolved or wrong-typed ref).OMG §10.3.1 - Error
eventSubprocessUntypedStartEvent sub-process (triggeredByEvent="true") start event has no event definition — the sub-process can never be triggered.OMG §10.2.4
Gateways (22)
- Warning
gatewayFanOutDecision gateways need 2+ on the in or out side; parallel pass-throughs flagged separately.In-depth - Error
invalidDefaultFlowGateway default attribute must point to a flow defined in the same scope.OMG §10.6.2 - Error
defaultFlowNoConditionA gateway's default sequence flow must not carry a <conditionExpression> — the default fires when all sibling conditions are false.OMG §10.5.3 - Error
defaultFlowForeignSourceA gateway's default flow must originate from this gateway (sourceRef === gateway.id).OMG §10.6.2 - Info
complexGatewayHasActivationConditionComplex gateway without <activationCondition> has implementation-defined firing semantics.OMG §10.6.6 - Warning
noDefaultFlowOnGatewayDiverging exclusive/inclusive gateway with 2+ conditional outflows but no default attribute.OMG §10.6.2 - Warning
complexGatewayMissingDefaultDiverging complex gateway without a default attribute — routing is undefined when no condition matches.OMG §10.6.6 - Warning
missingConditionExpressionNon-default outflow of exclusive/inclusive gateway lacks a conditionExpression (gateway has a default attribute).OMG §10.6.2 - Error
eventBasedGatewayTargetsEvent-based gateway outflows must target only intermediate catch event or receive task.OMG §10.6.3 - Error
conditionalFlowOnParallelGatewayParallel-gateway outflows fire unconditionally — conditionExpression is silently ignored.OMG §10.6.4 - Warning
conditionalFlowIntoEventBasedGatewaySequence flow into an eventBasedGateway carries a conditionExpression — event-based gateways race on events, not predicates.OMG §10.6.3 - Warning
conditionalFlowOutOfEventBasedGatewayOutgoing flow of an eventBasedGateway carries a conditionExpression — outflows fire when their target catch event occurs, not on a predicate.OMG §10.6.3 - Warning
conditionalFlowIntoJoinSequence flow into a converging gateway (join) carries a conditionExpression — joins consume tokens unconditionally, so the condition is silently ignored. - Warning
parallelJoinAfterExclusiveSplitParallel-join AND-gateway whose incoming branches all diverge from the same exclusive / event-based split — runtime deadlock. - Error
eventBasedGatewayInstantiateInstantiating eventBasedGateway must have zero incoming sequence flows.OMG §10.6.3 - Error
eventGatewayTypeEnum<eventBasedGateway> eventGatewayType must be one of "Exclusive" / "Parallel". - Warning
xorJoinAfterParallelSplitXOR-join receiving multiple parallel tokens from an upstream AND-split — downstream fires N times (lack of synchronization). - Warning
tokenExplosionOnAndSplitParallel-split with no common parallel-join downstream — tokens accumulate or fire end events independently. - Warning
xorConditionOverlapXOR / event-based gateway outflows have overlapping conditions on the same variable — engine resolves the tie by declaration order, which is engine-specific. - Warning
xorConditionGapXOR gateway has no default flow and its outflow conditions leave some values uncovered — tokens with those values are lost at runtime. - Warning
conditionTautologySequence-flow condition is always true (e.g. "x > 5 || x <= 5") — the branch fires regardless of input. - Warning
conditionContradictionSequence-flow condition is always false (e.g. "x > 100 && x < 50") — the branch is dead code.
Semantic references (11)
- Error
brokenReferenceGeneralized IDREF integrity: association / dataObjectReference / categoryValue / data*Association / callActivity must resolve to existing ids. - Warning
emptyTaskNameTasks should declare a non-empty name attribute. - Error
laneRefLane flowNodeRef must point to a flow node in the same process. - Warning
laneNodeUnassignedWhen a process declares lanes, every flow node should be assigned to exactly one lane (dual of laneRef).OMG §10.2.2 - Error
invalidRefTyped ref attributes (messageRef, signalRef, errorRef…) must resolve to declared roots. - Error
nodeInMultipleLanesA flow node must belong to at most one lane.OMG §9.2.2 - Warning
duplicateMessageRefUsageSame <message> referenced by 2+ distinct <messageFlow> elements — usually a copy-paste oversight. - Warning
dataObjectReferenceMissingRef<dataObjectReference> / <dataStoreReference> without target ref — the reference has no underlying data.OMG §10.4.5 - Warning
isForCompensationAlignmentActivity wired as a compensation handler must declare isForCompensation="true".OMG §10.5.5 - Warning
unattachedCompensationHandlerTask with isForCompensation="true" but no compensation <association> targets it — the handler will never fire.OMG §10.5.5 - Warning
brokenDataObjectRef<dataObjectReference dataObjectRef> resolves to a non-<dataObject> element — the typed reference is mis-pointing.
BPMN DI consistency (8)
- Warning
danglingDIElementBPMNShape / BPMNEdge references a semantic element that does not exist. - Info
missingShapeForFlowNodeFlow node has no corresponding <BPMNShape> — diagram cannot render it.In-depth - Info
missingEdgeForFlowSequence/message flow has no <BPMNEdge> — diagram cannot render the connection. - Info
malformedDIEdge<BPMNEdge> needs at least two <di:waypoint> children (source + target) — fewer makes the edge unrenderable. - Warning
diNegativeDimensions<BPMNShape> dc:Bounds width / height must be non-negative — negative values are rejected by BPMN modelers. - Warning
diZeroDimensions<BPMNShape> dc:Bounds width=0 or height=0 hides the shape from the rendered diagram. - Info
bpmnDiMissingDocument has <process> elements but no <BPMNDiagram> interchange section — viewers must auto-layout. - Warning
bpmnDiIncompleteSummary diagnostic: some flow nodes / sequence flows lack a corresponding <BPMNShape> / <BPMNEdge> in the DI section.
7PMG heuristics (4)
- Info
pmg1ModelSizeProcess should have <= 50 flow nodes — beyond this threshold understandability degrades (Mendling et al. 2010).OMG 7PMG-1 - Info
pmg3SingleStartEndProcess should have exactly one start event and one end event — multiple entry/exit points fragment the semantics (Mendling et al. 2010).OMG 7PMG-3 - Info
pmg5OrGatewayAvoid OR (inclusive) gateways — their synchronisation semantics is hard to reason about (Mendling et al. 2010).OMG 7PMG-5 - Info
pmg6CyclomaticRatioCyclomatic complexity / node count should stay <= 0.35 — high structural complexity correlates with modeling errors (Mendling et al. 2010).OMG 7PMG-6