Skip to main content

Events

Events represent something that happens during a process: a process starts, something is waited for, a result is emitted, an exception arises, time passes. Each event combines a position (start, end, intermediate catch, intermediate throw, boundary) with an event definition that says what kind of trigger or effect is involved.

Event definitions

The engine supports the following event definition types. Not every type is valid at every position.

DefinitionXML elementUsed for
None(no event-definition child)Plain start/end/throw points; the simplest form
MessagemessageEventDefinition messageRef="..."Send or wait for a correlated message
TimertimerEventDefinition with timeDate, timeDuration, or timeCycle childSchedule, wait, or fire on a cycle
SignalsignalEventDefinition signalRef="..."Broadcast or wait for a named signal
LinklinkEventDefinition name="..."In-process "goto" between throw and catch
ErrorerrorEventDefinition errorRef="..."Throw or catch a business error
EscalationescalationEventDefinition escalationRef="..."Throw or catch an escalation up the scope hierarchy
CompensationcompensateEventDefinitionTrigger or handle compensation for completed activities
ConditionalconditionalEventDefinition with condition childFire when a FEEL expression turns true
TerminateterminateEventDefinitionEnd the enclosing scope immediately

messageRef, signalRef, errorRef, and escalationRef must reference a top-level <message> / <signal> / <error> / <escalation> declaration in the same <definitions> block — see Global definitions.

Position × definition compatibility

StartEndIntermediate catchIntermediate throwBoundary
None
Message
Timer
Signal
Link
Errorevent sub-process only✓ (always interrupting)
Escalationevent sub-process only
Compensationevent sub-process only
Conditionalevent sub-process only
Terminate

Start events

Start events define how a process or sub-process begins.

Attributes

AttributeDefaultNotes
idRequired
nameOptional
isInterruptingtrueApplies to start events inside event sub-processes only. Ignored on top-level start events.

Auto-start behavior

When a process is deployed, typed start events are registered so an instance is started automatically when the trigger arrives:

DefinitionTrigger
NoneProcess started explicitly via API
MessageA message with the matching name is published
SignalA signal with the matching name is broadcast
TimerThe configured time arrives. Recurring expressions (R/PT1H) re-arm after each firing; one-shot (date) expressions fire once and deactivate

Re-deploying the process under a new version deactivates the previous version's auto-start registrations and arms the new ones.

Examples

<!-- None start event -->
<bpmn:startEvent id="start">
<bpmn:outgoing>f1</bpmn:outgoing>
</bpmn:startEvent>

<!-- Message start event -->
<bpmn:startEvent id="start-msg">
<bpmn:outgoing>f1</bpmn:outgoing>
<bpmn:messageEventDefinition messageRef="Msg_Payment" />
</bpmn:startEvent>

<!-- Recurring timer start (every hour) -->
<bpmn:startEvent id="start-timer">
<bpmn:outgoing>f1</bpmn:outgoing>
<bpmn:timerEventDefinition>
<bpmn:timeCycle xsi:type="bpmn:tFormalExpression">R/PT1H</bpmn:timeCycle>
</bpmn:timerEventDefinition>
</bpmn:startEvent>

<!-- Non-interrupting message start in an event sub-process -->
<bpmn:startEvent id="esp-start" isInterrupting="false">
<bpmn:outgoing>f1</bpmn:outgoing>
<bpmn:messageEventDefinition messageRef="Msg_Notify" />
</bpmn:startEvent>

Validation

CheckSeverity
Executable process has no start eventError
Start event has any incoming sequence flow (BPMN 2.0 §10.4.2)Error
Error / escalation / compensation start event placed outside an event sub-process (BPMN 2.0 §10.4.2 — these triggers are only legal as the starter of an event sub-process)Error
Conditional start event at top level — the engine does not auto-instantiate top-level conditional starts; use an event sub-process or external triggerWarning
messageRef / signalRef / errorRef / escalationRef references an unknown definitionError

End events

End events finish a path of execution. A process must have at least one reachable end event (or a node with no outgoing flow, which is treated as an implicit end).

Behavior by definition

DefinitionEffect
NoneCompletes the path normally
MessagePublishes a message, then completes. With quantum:taskDefinition set, a worker performs the dispatch; otherwise the engine publishes directly
ErrorThrows an error; propagates up the scope hierarchy to the nearest matching error boundary or error start event in an event sub-process
EscalationThrows an escalation up the scope chain to the nearest matching listener. With quantum:taskDefinition a worker performs the dispatch
TerminateCancels the nearest enclosing activity scope (sub-process, ad-hoc sub-process, or root process) and continues from that scope's outgoing flow. At the root, the entire instance terminates. A terminate inside a called process ends only the called process
CompensationTriggers compensation for completed activities in scope, or for the activity named by activityRef

Examples

<!-- None end event -->
<bpmn:endEvent id="end">
<bpmn:incoming>f_last</bpmn:incoming>
</bpmn:endEvent>

<!-- Error end event -->
<bpmn:endEvent id="end-error">
<bpmn:incoming>f_err</bpmn:incoming>
<bpmn:errorEventDefinition errorRef="Err_Timeout" />
</bpmn:endEvent>

<!-- Terminate end event -->
<bpmn:endEvent id="end-terminate">
<bpmn:incoming>f_abort</bpmn:incoming>
<bpmn:terminateEventDefinition />
</bpmn:endEvent>

<!-- Message end event dispatched by a worker -->
<bpmn:endEvent id="end-msg">
<bpmn:extensionElements>
<quantum:taskDefinition type="send-notification" />
</bpmn:extensionElements>
<bpmn:incoming>f_notify</bpmn:incoming>
<bpmn:messageEventDefinition messageRef="Msg_Done" />
</bpmn:endEvent>

Validation

CheckSeverity
End event has any outgoing sequence flow (BPMN 2.0 §10.4.3)Error
messageRef / errorRef / escalationRef references an unknown definitionError
Message end event with no messageRef and no quantum:taskDefinitionWarning (publishes a nameless message)
Escalation end event with no escalationRef and no quantum:taskDefinitionWarning (throws a nameless escalation)

Intermediate catch events

Intermediate catch events pause the token until an external trigger arrives, then advance.

Behavior by definition

DefinitionBehavior
MessageWaits for a correlated message matching the referenced name. If a buffered message is already available it fires immediately
Timer — timeDurationWaits the specified ISO 8601 duration from the moment the event is reached
Timer — timeDateWaits until the specified ISO 8601 datetime
Timer — timeCycleFires repeatedly on the cycle
SignalWaits for a broadcast matching the referenced name; checks the buffer first
LinkReceives control from a matching link throw event of the same name in the same scope. Acts as a goto target

A catch event placed immediately after an event-based gateway must have exactly one incoming flow (from the gateway).

Examples

<!-- Message catch -->
<bpmn:intermediateCatchEvent id="catch-msg" name="Wait for Payment">
<bpmn:incoming>f1</bpmn:incoming>
<bpmn:outgoing>f2</bpmn:outgoing>
<bpmn:messageEventDefinition messageRef="Msg_Payment" />
</bpmn:intermediateCatchEvent>

<!-- Timer catch (duration) -->
<bpmn:intermediateCatchEvent id="wait-5m" name="Wait 5 min">
<bpmn:incoming>f1</bpmn:incoming>
<bpmn:outgoing>f2</bpmn:outgoing>
<bpmn:timerEventDefinition>
<bpmn:timeDuration xsi:type="bpmn:tFormalExpression">PT5M</bpmn:timeDuration>
</bpmn:timerEventDefinition>
</bpmn:intermediateCatchEvent>

<!-- Signal catch -->
<bpmn:intermediateCatchEvent id="catch-signal" name="Receive Abort">
<bpmn:incoming>f1</bpmn:incoming>
<bpmn:outgoing>f2</bpmn:outgoing>
<bpmn:signalEventDefinition signalRef="Sig_Abort" />
</bpmn:intermediateCatchEvent>

<!-- Link catch (jump target) -->
<bpmn:intermediateCatchEvent id="catch-link" name="Land">
<bpmn:outgoing>f3</bpmn:outgoing>
<bpmn:linkEventDefinition name="LinkA" />
</bpmn:intermediateCatchEvent>

Validation

CheckSeverity
No event definition presentError
Catch event has anything other than exactly one outgoing sequence flow (BPMN 2.0 §10.5.4 — intermediate events have one input, one output)Error
Catch event after an event-based gateway has more than one incoming flowError
messageRef / signalRef references an unknown definitionError

Intermediate throw events

Intermediate throw events emit something — a message, signal, escalation, link, or compensation trigger — and then advance immediately. A throw with no event definition is a pass-through.

Behavior by definition

DefinitionBehavior
NonePure pass-through
MessagePublishes the message with the current scope variables. If quantum:taskDefinition is also set, switches to external-job mode (see below)
SignalBroadcasts the signal to all subscribers
LinkTransfers control to the matching link catch in the same scope. Acts as a goto
EscalationThrows an escalation up to the nearest matching listener
CompensationTriggers compensation; activityRef can target a specific completed activity

Execution modes (apply to every throw kind)

A throw event with quantum:taskDefinition type="..." switches into worker-driven mode regardless of which event definition is attached: the engine creates a job, the worker performs the actual publish/throw, and the throw advances when the worker reports completion. In this mode the messageRef / escalationRef / etc. become optional — the worker controls what is dispatched.

ModeWhen activeBehavior
Direct dispatchNo quantum:taskDefinitionEngine publishes / throws immediately and advances
External jobquantum:taskDefinition type="..." is setEngine creates a persistent job; throw advances when the worker completes the job

The same applies to message and escalation end events.

Examples

<!-- Signal throw -->
<bpmn:intermediateThrowEvent id="throw-signal" name="Broadcast Abort">
<bpmn:incoming>f1</bpmn:incoming>
<bpmn:outgoing>f2</bpmn:outgoing>
<bpmn:signalEventDefinition signalRef="Sig_Abort" />
</bpmn:intermediateThrowEvent>

<!-- Escalation throw -->
<bpmn:intermediateThrowEvent id="throw-esc" name="Escalate">
<bpmn:incoming>f1</bpmn:incoming>
<bpmn:outgoing>f2</bpmn:outgoing>
<bpmn:escalationEventDefinition escalationRef="Esc_Review" />
</bpmn:intermediateThrowEvent>

<!-- Link throw (jump source) -->
<bpmn:intermediateThrowEvent id="throw-link" name="Jump">
<bpmn:incoming>f1</bpmn:incoming>
<bpmn:linkEventDefinition name="LinkA" />
</bpmn:intermediateThrowEvent>

<!-- Compensation throw — compensate everything completed in scope -->
<bpmn:intermediateThrowEvent id="throw-comp" name="Compensate All">
<bpmn:incoming>f1</bpmn:incoming>
<bpmn:outgoing>f2</bpmn:outgoing>
<bpmn:compensateEventDefinition />
</bpmn:intermediateThrowEvent>

Validation

CheckSeverity
messageRef / signalRef / escalationRef references an unknown definitionError
Message throw with no messageRef and no quantum:taskDefinition (publish has no name to correlate against)Error
Escalation throw with no escalationRef, no inline escalationCode, and no quantum:taskDefinition (no listener can match)Error
Link throw has no matching link catch with the same name in the same scopeError

Boundary events

Boundary events are attached to an activity (task, sub-process, or call activity) and fire while the activity is running.

Attributes

AttributeDefaultNotes
idRequired
nameOptional
attachedToRefRequired. ID of the host activity (must be in the same scope)
cancelActivitytruetrue = interrupting (host is cancelled, only the boundary path continues); false = non-interrupting (host continues; a parallel token starts from the boundary). Ignored on compensation boundaries

Behavior by definition

DefinitionNotes
MessageFires when a correlated message arrives while the host is active
TimertimeDuration and timeDate fire once. timeCycle (e.g. R3/PT1M) fires repeatedly and is non-interrupting only
ErrorAlways interrupting. Fires when the host throws a matching error
SignalFires when the matching signal is broadcast while the host is active
EscalationFires when the host throws a matching escalation
ConditionalFires when the FEEL condition evaluates to true while the host is active
CompensationMarks this boundary as the trigger for a compensation handler. Linked to the handler activity by an <association> element. Does not use cancelActivity — fires only when compensation is explicitly thrown for the host (after the host has completed), and never cancels the host

Examples

<!-- Interrupting timer boundary: 30-minute timeout -->
<bpmn:boundaryEvent id="timer-boundary" attachedToRef="long-task" cancelActivity="true">
<bpmn:outgoing>f_timeout</bpmn:outgoing>
<bpmn:timerEventDefinition>
<bpmn:timeDuration xsi:type="bpmn:tFormalExpression">PT30M</bpmn:timeDuration>
</bpmn:timerEventDefinition>
</bpmn:boundaryEvent>

<!-- Non-interrupting message boundary: send a reminder while waiting -->
<bpmn:boundaryEvent id="msg-boundary" attachedToRef="approval-task" cancelActivity="false">
<bpmn:outgoing>f_notify</bpmn:outgoing>
<bpmn:messageEventDefinition messageRef="Msg_Reminder" />
</bpmn:boundaryEvent>

<!-- Error boundary: handle a known failure type -->
<bpmn:boundaryEvent id="err-boundary" attachedToRef="service-task" cancelActivity="true">
<bpmn:outgoing>f_error</bpmn:outgoing>
<bpmn:errorEventDefinition errorRef="Err_Timeout" />
</bpmn:boundaryEvent>

<!-- Compensation boundary, with handler linked by association -->
<bpmn:boundaryEvent id="comp-boundary" attachedToRef="book-hotel">
<bpmn:compensateEventDefinition />
</bpmn:boundaryEvent>
<bpmn:serviceTask id="cancel-hotel" name="Cancel Hotel" isForCompensation="true">
<bpmn:extensionElements>
<quantum:taskDefinition type="cancel-hotel-worker" />
</bpmn:extensionElements>
</bpmn:serviceTask>
<bpmn:association id="assoc1" sourceRef="comp-boundary" targetRef="cancel-hotel" />

<!-- Cyclic non-interrupting timer: fire every minute, up to 3 times -->
<bpmn:boundaryEvent id="cycle-boundary" attachedToRef="long-task" cancelActivity="false">
<bpmn:outgoing>f_tick</bpmn:outgoing>
<bpmn:timerEventDefinition>
<bpmn:timeCycle>R3/PT1M</bpmn:timeCycle>
</bpmn:timerEventDefinition>
</bpmn:boundaryEvent>

Validation

CheckSeverity
attachedToRef is empty or doesn't resolve to an activity in the same scopeError
No event definition presentError
Error boundary has cancelActivity="false"Error
Timer boundary has none of timeDuration/timeDate/timeCycleError
Timer boundary uses timeCycle while interruptingError
Timer boundary mixes timeCycle with timeDuration or timeDateWarning (timeCycle wins)
Conditional boundary has empty conditionError
Compensation boundary has no associated handler activityError
Compensation handler is not marked isForCompensation="true"Error
messageRef / signalRef / errorRef / escalationRef references an unknown definitionError