$flow — Workflow Directive
Reads structural metadata about the current workflow and its nodes — name, version, node definitions, and the active execution path.
| Property | Value |
|---|---|
| Directive name | flow |
| Required isolation level | Safe |
| Project | FlowExecution.Services |
| Data source | IWorkflowFlowFacts |
Complete Path Reference
| Path | Type | Example | Description |
|---|---|---|---|
$flow.current.id | String (GUID) | wf-a4c2... | Unique ID of the workflow definition |
$flow.current.name | String | Invoice Processing | Human-readable workflow name |
$flow.current.version | String | 3.1.0 | Workflow definition version |
$flow.current.description | String | Handles PDF invoice ingestion... | Workflow description from definition |
$flow.current.tags | Array | ["finance","automated"] | Tags applied to this workflow |
$flow.current.nodeCount | Number | 14 | Total number of nodes in the workflow |
$flow.current.isSubWorkflow | Boolean | false | True if this workflow was called by another |
$flow.current.createdAt | String (ISO 8601) | 2024-01-10T09:00:00Z | When the workflow definition was created |
$flow.current.updatedAt | String (ISO 8601) | 2024-03-01T14:30:00Z | Last time the workflow was modified |
$flow.node.key | String | SendEmail | Key of the node currently being evaluated |
$flow.node.type | String | EmailSend | Node type identifier |
$flow.node.label | String | Send Invoice Email | Human-readable label from flow designer |
$flow.node.position.x | Number | 420 | X canvas position (designer metadata) |
$flow.node.position.y | Number | 210 | Y canvas position (designer metadata) |
$flow.thread.id | String | t_main | Current execution thread ID |
$flow.thread.name | String | main | Logical name of this thread |
$flow.thread.isParallel | Boolean | false | True if this thread is inside a ParallelFork |
Complex Scenarios
Scenario 1 — Versioned Audit Trail
Stamp every audit event with the exact workflow version that processed it:
// Audit log node — structured record
{
"event": "workflow_completed",
"workflowId": "{@ $flow.current.id }",
"workflowName":"{@ $flow.current.name }",
"version": "{@ $flow.current.version }",
"executionId": "{@ $exec.executionId }",
"timestamp": "{@ $ctx.now }"
}
Scenario 2 — Dynamic Email Subject Based on Workflow Name
Build a notification subject that includes the workflow and node context:
Email subject
[{@ $ctx.tenant.name }] {@ $flow.current.name } — Action required at node "{@ $flow.node.label }"
[Acme Corp] Invoice Processing — Action required at node "Send Invoice Email"
Scenario 3 — Detecting Sub-workflow Context
A shared utility workflow behaves differently when called as a sub-workflow vs. a standalone trigger:
// IfCondition: adjust logging verbosity for sub-workflows
{@ $js`
const isSub = context.flow.current.isSubWorkflow;
// When called from parent, reduce log noise
return isSub ? 'minimal' : 'full';
` }
// In the log node: append parent execution only when applicable
{@ $js`
if (context.flow.current.isSubWorkflow) {
return 'Parent: ' + (context.exec.parentExecutionId || 'unknown');
}
return 'Top-level execution';
` }
Scenario 4 — Node Type Routing in Generic Error Handler
A catch block uses node type to pick the right recovery strategy:
// CatchBlock: route to different recovery nodes based on failing node type
{@ $js`
const nodeType = context.flow.node.type;
if (nodeType === 'HttpRequest') return 'http_retry';
if (nodeType === 'EmailSend') return 'email_fallback';
if (nodeType === 'DbQuery') return 'db_circuit_break';
return 'generic_error';
` }
Scenario 5 — Parallel Thread Status in Summary Node
After a ParallelFork, a merge node uses thread info to build a summary:
// Merge node — confirm both threads completed
{
"mergedFrom": [
{ "thread": "{@ $flow.thread.id }", "parallel": {@ $flow.thread.isParallel } }
],
"workflow": "{@ $flow.current.name } v{@ $flow.current.version }"
}
Scenario 6 — Workflow Tag-Based Feature Toggling
Check workflow tags at runtime to decide whether to enable a new processing path:
// IfCondition: only run new pricing engine if workflow is tagged "beta"
{@ $js`
const tags = context.flow.current.tags || [];
return tags.includes('beta') && tags.includes('pricing-v2');
` }
// true → route to new pricing engine branch
// false → route to stable pricing engine
Common Errors
| Error | Cause | Fix |
|---|---|---|
PathNotFound: current.description | Workflow has no description set in designer | Use @default:No description; add description in Flow Studio |
PathNotFound: current.tags | No tags applied to this workflow | Use @default:[]; guard with $js array check |
PathNotFound: thread.name | Running on default thread which may have no explicit name | Use @default:main |