Portal Community
PropertyValue
Directive nameexec (or execFacts in current implementation)
Required isolation levelSafe
ProjectFlowExecution.Services
Data sourceINodeExecutionFacts

Complete Path Reference

PathTypeExampleDescription
$exec.executionIdString (GUID)e8f23a1b-...Unique ID for this execution instance
$exec.threadIdStringt_mainCurrent execution thread identifier
$exec.nodeKeyStringSendInvoiceEmailKey of the currently executing node
$exec.startedAtString (ISO 8601)2024-03-15T10:22:01ZWhen this execution started
$exec.triggeredByStringWebhookTrigger type: Manual / Webhook / Scheduled / Form
$exec.triggeredByUserIdNumber (nullable)42ID of user who triggered (null for scheduled/webhook)
$exec.retryCountNumber0How many times this node has been retried
$exec.isRetryBooleanfalsetrue if this is a retry attempt
$exec.parentExecutionIdString (nullable)d3a8...ID of the parent execution (set for sub-workflows)
$exec.correlationIdString (nullable)ORDER-2024-001Business correlation ID passed at trigger time

Complex Scenarios

Scenario 1 — Idempotency Key for External API Calls

Use the execution ID as an idempotency key to prevent duplicate submissions on retry:

HTTP header: Idempotency-Key
{@ $exec.executionId }-{@ $exec.nodeKey }
e8f23a1b-4c2d-...-SendPayment — unique per execution AND node

Scenario 2 — Skipping Expensive Operations on Retry

If a node is being retried, skip a slow data-fetch step that already succeeded:

// IfCondition: "Skip if retry"
{@ $exec.isRetry }
// true → skip to next node (data already fetched in first attempt)
// false → run the full data fetch

// More nuanced: only skip if retried more than once
{@ $js`return context.exec.retryCount > 1` }

Scenario 3 — Structured Log Entry with Correlation

// Structured audit log node field:
{
  "timestamp":     "{@ $ctx.now }",
  "executionId":   "{@ $exec.executionId }",
  "correlationId": "{@ $exec.correlationId @default:none }",
  "workflow":      "{@ $flow.current.name }",
  "node":          "{@ $exec.nodeKey }",
  "triggeredBy":   "{@ $exec.triggeredBy }",
  "userId":        {@ $exec.triggeredByUserId @default:null }
}

Scenario 4 — Sub-workflow Traceability

When a sub-workflow runs, it can reference its parent execution for full traceability:

// Sub-workflow creates a child execution record linking to parent:
POST /api/audit/execution
{
  "executionId":       "{@ $exec.executionId }",
  "parentExecutionId": "{@ $exec.parentExecutionId @default:root }",
  "workflowId":        "{@ $flow.current.id }",
  "tenantId":          {@ $ctx.tenant.id }
}

Scenario 5 — Time-Based Execution Reporting

Build a duration report by comparing execution start to current time:

{@ $js`
const started = new Date(context.exec.startedAt);
const now     = new Date(context.ctx.now);
const seconds = Math.round((now - started) / 1000);
return seconds < 60 ? seconds + 's' : Math.round(seconds/60) + 'm';
` }
// "47s" or "3m" — human-readable execution duration so far

Common Errors

ErrorCauseFix
PathNotFound: correlationIdNo correlation ID was passed at trigger timeUse @default:none; make correlation ID optional in your design
PathNotFound: parentExecutionIdThis is a top-level execution, not a sub-workflowUse @default to handle both top-level and sub-workflow contexts