Finally Block — Configuration
Placement rules, scope mechanics, and variable availability in the Finally Block.
No configuration required. The Finally Block node has no configurable properties. It is a structural node that marks the start of an unconditional cleanup scope. Simply place it after the Catch Block node in your workflow and connect the nodes that should always run.
Minimal Configuration Object
{
"nodeType": "FinallyBlock",
"id": "finally_payment_cleanup",
"label": "Finally — Payment Cleanup"
}
Placement and Scope Rules
- Place the Finally Block after the Catch Block at the same graph level — it is a sibling of both the Try Block and Catch Block nodes, not inside any scope.
- The Finally Block is optional — a Try/Catch pair is valid without a Finally Block. Only add it when you have operations that genuinely must run unconditionally.
- Only one Finally Block per Try/Catch pair — you cannot have multiple Finally Blocks for the same try scope. Consolidate all cleanup logic into a single finally scope.
- Avoid long-running operations in the Finally Block — since it always runs, expensive operations here add latency to every workflow execution, including the success path. Keep finally scope lean: logging, status updates, and resource release only.
- Do not throw unhandled exceptions in the Finally Block — if a node inside the finally scope throws an exception and there is no outer try/catch to catch it, the workflow will terminate with an unhandled exception, overriding the original error handling. Protect risky finally-scope nodes with their own nested Try/Catch if needed.
Variable Availability in Finally Scope
The following data is accessible in all nodes connected to the Finally Block's success port:
| Variable / Context | Available? | Notes |
|---|---|---|
Workflow variables ($var.*) |
Yes | All variables set before and during both try and catch scopes are accessible. |
Exception variables ($mem.__exception_*) |
If error occurred | Populated if an exception was caught. Null/absent if the try scope succeeded. Use $mem.__exception_type__ != null to distinguish outcomes. |
Execution context ($ctx.*) |
Yes | Workflow instance ID, run ID, definition ID, and timestamps always available. |
Node outputs ($nodes.*) |
Partial | Outputs from nodes that executed before the exception are available. Outputs from the exception-throwing node and nodes that were skipped are not. |
Detecting outcome in Finally: To write different audit log entries for success vs. error, use an If Condition node as the first node inside the finally scope with the expression
$mem.__exception_type__ != null. The true path handles error cleanup; the false path handles success cleanup. Both paths can then converge on a common log node.