Skip to content

Supported BPMN elements

Orvanta’s BPMN engine executes a defined subset of BPMN 2.0 — not the full specification. This page lists exactly what runs. An element outside this list fails deploy-time validation with an explicit error naming the element; the engine never silently drops or mis-executes a construct it doesn’t recognise.

This table is derived from the engine, not hand-maintained. A test in orvanta-bpmn renders every ElementKind and recognised tag, plus its support status, to a committed element-support.json and asserts the two stay byte-identical — adding or changing a construct’s support fails that test until the record (and, in turn, this page) is updated. If you find a mismatch, the code and element-support.json are right and this page is wrong.

BPMN constructBehaviour
startEvent (no event definition)Starts the process, advances to its single outgoing flow.
startEvent + timerEventDefinitionSame as a plain start event — the timer is the instantiation trigger; it has already fired by the time a token exists.
endEvent (no event definition)Consumes the token.
endEvent + errorEventDefinitionRaises an error carrying its resolved error code. Caught by the nearest enclosing interrupting boundary error event; if uncaught, parks the process as an incident.
intermediateCatchEvent + timerEventDefinitionParks the token until the timer fires.
intermediateCatchEvent + messageEventDefinitionParks the token waiting for an external event.
intermediateThrowEvent (no event definition)Pass-through — a bare throw event has nothing to throw, so it just advances.
boundaryEvent + errorEventDefinition, interrupting (cancelActivity true or absent)Receives a caught error and routes the token into the handler branch.
scriptTaskDispatches the bound script as a child job.
serviceTaskDispatches the bound script as a child job (same binding mechanism as scriptTask).
serviceTask + flowable:type="external-worker" (or the legacy "external" spelling)A wait state, not something the engine dispatches itself: it parks the token and exposes a topic + payload through the status projection for an external worker to fetch, then complete, fail, or throw a BPMN error against, over a REST round-trip.
serviceTask + flowable:type="dmn" (Flowable’s decision task)Compiles to the same kind as businessRuleTask and evaluates the same way — see below. The decision reference comes from a <flowable:field> (decisionTableReferenceKey or decisionServiceReference) instead of orvanta:decisionRef.
userTaskParks the token waiting for an external completion signal.
businessRuleTaskEvaluates its linked DMN decision table synchronously, inline, on the worker. A reference to a <decisionService> rather than a plain decision deploys with a warning, evaluating only the single decision it names — see Decision Services and DRDs.
task (untyped)Pure pass-through — no data transform, no child job, no wait. Standard BPMN semantics for an abstract task.
manualTaskPure pass-through — identical runtime behaviour to an untyped task. BPMN 2.0 gives it no engine semantics of its own (it models work done outside the system: approvals, phone calls, physical handling), so there’s nothing for the engine to do but advance past it. Kept as its own catalog entry rather than folded into task so the editor round-trips the author’s original tag instead of silently rewriting it.
subProcess (embedded, non-transaction, non-event)Activates a child scope. The parent token doesn’t get consumed — it parks as the anchor until every token and join inside the scope drains.
exclusiveGatewayEvaluates each outgoing condition and routes down exactly one flow.
parallelGatewayStructured AND split/join.
inclusiveGatewayStructured OR split/join — activates every branch whose condition is truthy; the paired join fires on exactly that subset.

That’s 18 element kinds, matching the engine’s ElementKind enum (Task and Gateway each carry a handful of sub-kinds counted individually above). manualTask and the flowable:type="dmn" service task both reuse an existing kind rather than adding one; the external-worker service task (flowable:type="external-worker"/"external") is its own kind and is the 18th.

flowable:async, flowable:asyncLeave/asyncAfter, and flowable:exclusive apply across every element kind above — not a property of any one of them — and are covered separately in Execution semantics.

These parse as recognised BPMN tags but compile to Unsupported and are rejected at deploy time — they block deploying a process, they don’t run with reduced fidelity:

  • callActivity
  • Any multiInstance marker, on any activity type
  • Event sub-processes (transaction, triggeredByEvent)
  • Non-interrupting boundary events (any type)
  • Boundary events of the message, signal, escalation, or conditional flavour
  • receiveTask, sendTask
  • adHocSubProcess
  • terminateEndEvent
  • complexGateway, eventBasedGateway
  • Signal/escalation start, throw, and catch events
  • dataObject/dataObjectReference, dataStore/dataStoreReference, and property — recognised, then refused; their subtrees are skipped rather than modelled

Pools and lanes (laneSet/lane) are parsed but ignored — their subtree isn’t rejected, but it also isn’t modelled or executed. Treat them as diagram-only.

If you’re migrating an existing process definition, see Importing from Flowable/Camunda for what this means for real-world BPMN XML, and the measured conformance rate against a corpus of production Flowable processes.