PENDING
<rect x="164" y="110" width="90" height="40" rx="20" fill="none" stroke="currentColor" stroke-width="1.5" opacity=".8"/> <text x="209" y="135">READY</text>
<rect x="324" y="110" width="100" height="40" rx="20" fill="none" stroke="currentColor" stroke-width="2"/> <text x="374" y="135">RUNNING</text>
<rect x="484" y="110" width="110" height="40" rx="20" fill="currentColor" opacity=".13"/> <rect x="484" y="110" width="110" height="40" rx="20" fill="none" stroke="currentColor" stroke-width="1.5"/> <text x="539" y="135">SUCCEEDED</text>
<rect x="484" y="192" width="110" height="40" rx="20" fill="currentColor" opacity=".13"/> <rect x="484" y="192" width="110" height="40" rx="20" fill="none" stroke="currentColor" stroke-width="1.5"/> <text x="539" y="217">FAILED</text>
<rect x="300" y="230" width="100" height="40" rx="20" fill="none" stroke="currentColor" stroke-width="1.5" stroke-dasharray="4 3" opacity=".8"/> <text x="350" y="255">RETRYING</text>
<rect x="150" y="230" width="100" height="40" rx="20" fill="currentColor" opacity=".13"/> <rect x="150" y="230" width="100" height="40" rx="20" fill="none" stroke="currentColor" stroke-width="1.5"/> <text x="200" y="255">SKIPPED</text>
<rect x="640" y="110" width="115" height="40" rx="20" fill="currentColor" opacity=".13"/> <rect x="640" y="110" width="115" height="40" rx="20" fill="none" stroke="currentColor" stroke-width="1.5"/> <text x="697" y="135">CANCELLED</text>
<rect x="640" y="192" width="130" height="40" rx="20" fill="currentColor" opacity=".13"/> <rect x="640" y="192" width="130" height="40" rx="20" fill="none" stroke="currentColor" stroke-width="1.5"/> <text x="705" y="217">COMPENSATED</text>
<text x="440" y="30" font-size="11.5" opacity=".65">shaded = terminal</text> </g> </svg> </div>
state meaning terminal PENDINGcreated; join condition not yet satisfied no READYjoin condition satisfied; may be scheduled no RUNNINGexecuting no RETRYINGan attempt failed; retries remain; waiting out the backoff no SUCCEEDEDcompleted successfully yes SKIPPEDreached , and its guard evaluated false — a successful outcomeyes FAILEDfailed with retries exhausted yes CANCELLEDterminated before completion yes COMPENSATEDhad succeeded, then was rolled back yes
6.2 Legal transitions#
A conforming runtime MUST NOT perform any transition not listed here.
from to when PENDINGREADYjoin condition satisfied PENDINGCANCELLEDinstance cancelled while the node was still waiting READYRUNNINGscheduled, guard true READYSKIPPEDguard evaluated false READYCANCELLEDinstance cancelled, or a sibling satisfied an any join RUNNINGSUCCEEDEDexecution completed RUNNINGFAILEDexecution failed with no retries remaining RUNNINGRETRYINGexecution failed with retries remaining RUNNINGCANCELLEDcancelled — only if idempotent="true" RETRYINGREADYbackoff elapsed RETRYINGFAILEDretry budget exhausted, or a non-retryable error class RETRYINGCANCELLEDinstance cancelled SUCCEEDEDCOMPENSATEDcompensation ran during unwinding
Everything else is a runtime defect.
6.2.1 Cancelling a RUNNING node#
A runtime MUST NOT cancel a RUNNING node declared idempotent="false". It MUST let the attempt finish and then discard the result.
Interrupting a non-idempotent action mid-flight leaves the world in a state nobody can describe: was the payment sent? did the arm complete the grasp? A result that is discarded is at least a known outcome.
6.3 SKIPPED is a success#
The state most often implemented wrongly.
SKIPPED is terminal and successful . A node whose guard evaluated false did exactly what the document asked. So:
outgoing control edges are satisfied; outgoing data edges are satisfied for scheduling, but the values areunavailable (see §5.6 );
outgoing error edges are not taken — nothing failed.
Treating skip as failure means any optional step halts everything after it, which is not what a guard means.
6.4 PENDING at completion is normal#
A node that was never reached stays PENDING when the instance completes.
This is the expected outcome for the branch a decision did not take. It is not an error, and a runtime MUST NOT report the instance as failed because nodes remain PENDING.
Distinguish it from the two states it is most often confused with. All three are ordinary outcomes, and an incident review needs to tell them apart:
state means successors PENDING at completionnever reached — no path arrivedalso not reached SKIPPEDreached , and its guard was falsecontrol successors still run CANCELLEDreached and started , then stoppednot reached
Conflating PENDING with SKIPPED makes the untaken branch of every decision report as a success that ran.
6.5 Loop iterations#
A loop node has its own lifecycle, and so does each iteration of its body. Iteration states are scoped to the iteration and do not overwrite one another — iteration 3 failing does not put the body node in FAILED for iterations 4 onward.
The loop node's own outcome follows onItemFailure:
onItemFailureloop node reaches fail (default)FAILED on the first iteration failurecontinueSUCCEEDED if any iteration succeeded; FAILED if all failedbreakSUCCEEDED, stopping at the first failure
6.6 Traces#
A runtime SHOULD emit a trace of state transitions. A trace entry SHOULD carry the node id, both states, a timestamp, the attempt number, and for FAILED, the error class and message.
Conformance at Executing and Full level compares the normalised sequence of transitions , not timing and not the interleaving of independent branches — two runtimes may schedule unrelated work in different orders. What they may not do is disagree about whether a node ran, was skipped, retried, failed or was compensated. See conformance .
On this page