Execute Workflow Node

Execute Workflow Node

Overview

The Execute Workflow node runs another published workflow and waits for its completion. This enables workflow composition, reusability, and modular design by allowing workflows to call other workflows.

When to Use

Use an Execute Workflow node when you need to:

  • Reuse common workflow logic across multiple workflows
  • Break complex workflows into smaller, manageable pieces
  • Create modular, composable workflows
  • Call specialized workflows for specific tasks
  • Maintain separation of concerns
  • Version workflow components independently

Configuration

Workflow Selection

Workflow: Choose which published workflow to execute

  • Only published workflows appear in the dropdown
  • The selected workflow must have a defined input schema (if it accepts parameters)
  • Workflow must be in the same organization

Input Parameters

Provide input data for the child workflow:

  • Input fields are automatically generated based on the child workflow’s trigger schema
  • Each field can be a literal value or JSONPath expression
  • Required fields must be provided

Output Schema

The output schema is automatically generated from the child workflow’s Set Output nodes:

  • Shows what data the child workflow will return
  • Available at $.results.<nodeId> after execution
  • Structure matches the child workflow’s output

How It Works

  1. Workflow Selected: Choose which workflow to execute
  2. Input Mapped: Map data from current workflow to child workflow inputs
  3. Execution Starts: Child workflow begins execution
  4. Wait for Completion: Parent workflow pauses until child completes
  5. Collect Output: Child workflow’s output becomes available
  6. Continue: Parent workflow resumes with child’s results

Examples

Example: Validate Address Workflow

Parent Workflow: Order Processing Child Workflow: Address Validator Node ID: validateShippingAddress

Input:

  • street: $.results.trigger.shippingAddress.street
  • city: $.results.trigger.shippingAddress.city
  • state: $.results.trigger.shippingAddress.state
  • zip: $.results.trigger.shippingAddress.zip

Output Schema (from child workflow’s Set Output):

{
  "valid": boolean,
  "normalized": {
    "street": string,
    "city": string,
    "state": string,
    "zip": string
  },
  "confidence": number
}

Access Results:

$.results.validateShippingAddress.valid
$.results.validateShippingAddress.normalized.street
$.results.validateShippingAddress.confidence

Example: Credit Check Workflow

Parent Workflow: Loan Application Child Workflow: Credit Score Checker Node ID: checkCredit

Input:

  • applicantId: $.results.trigger.applicantId
  • ssn: $.results.trigger.ssn
  • requestType: "loan_application"

Flow:

gatherApplicantInfo
└─ checkCredit (Execute Workflow: Credit Score Checker)
   └─ Conditional: evaluateScore
      ├─ Score >= 700 → approveApplication
      └─ Score < 700 → requestAdditionalInfo

Access Credit Score:

$.results.checkCredit.creditScore
$.results.checkCredit.riskLevel

Example: Email Notification Workflow

Parent Workflow: Order Fulfillment Child Workflow: Send Order Email Node ID: sendConfirmation

Input:

  • recipientEmail: $.results.trigger.customerEmail
  • orderNumber: $.results.createOrder.id
  • items: $.results.createOrder.items
  • total: $.results.calculateTotal.amount
  • template: "order_confirmation"

Access Output:

$.results.sendConfirmation.messageId
$.results.sendConfirmation.sentAt

Example: Data Enrichment Pipeline

Parent Workflow: Lead Processing Node ID: enrichLead

Flow:

receiveLead
└─ Parallel: enrichData
   ├─ Branch 1: Execute Workflow (Company Lookup)
   │  Input: companyDomain: $.trigger.email
   │  Output: $.results.companyLookup.companyData
   │
   ├─ Branch 2: Execute Workflow (Email Verification)
   │  Input: email: $.trigger.email
   │  Output: $.results.emailVerify.isValid
   │
   └─ Branch 3: Execute Workflow (Social Profile Finder)
      Input: name: $.trigger.name, company: $.trigger.company
      Output: $.results.socialFinder.profiles

└─ Function: mergeEnrichedData
   └─ Set Output: enrichedLead

Example: Multi-Step Approval

Parent Workflow: Budget Request Child Workflow: Approval Request Node ID: managerApproval

Input:

  • requestType: "budget"
  • amount: $.results.trigger.requestedAmount
  • department: $.results.trigger.department
  • approverEmail: $.results.getDepartmentManager.email
  • description: $.results.trigger.description

Flow:

validateRequest
└─ managerApproval (Execute Workflow: Approval Request)
   └─ Conditional: checkApproval
      ├─ Approved
      │  └─ directorApproval (Execute Workflow: Approval Request)
      │     └─ Conditional: checkDirectorApproval
      │        ├─ Approved → allocateBudget
      │        └─ Rejected → notifyRejection
      └─ Rejected → notifyRejection

Accessing Child Workflow Output

Output from the executed workflow is available directly at:

$.results.<nodeId>

If the child workflow has a Set Output node with fields:

{
  "status": "success",
  "data": { ... },
  "processedAt": "2025-12-22T10:00:00Z"
}

Access individual fields:

$.results.<nodeId>.status
$.results.<nodeId>.data
$.results.<nodeId>.processedAt

Best Practices

  • Published Workflows Only: Only published workflows can be executed
  • Define Input Schema: Ensure child workflows have clear input schemas
  • Define Output Schema: Use Set Output nodes in child workflows for clear outputs
  • Version Management: Be aware that changes to child workflows affect all parents
  • Error Handling: Set onFailure paths for when child workflows fail
  • Testing: Test child workflows independently before using in parents
  • Documentation: Document what each child workflow does and expects
  • Avoid Deep Nesting: Limit workflow nesting depth (2-3 levels max)
  • Modular Design: Keep child workflows focused on single responsibilities

Common Patterns

Reusable Validation

Parent Workflows (Order, Returns, Exchanges)
└─ All call: Execute Workflow (Address Validator)

One validation workflow used by multiple parent workflows.

Sequential Workflow Steps

Step 1: Execute Workflow (Data Collection)
└─ Step 2: Execute Workflow (Data Validation)
   └─ Step 3: Execute Workflow (Data Processing)
      └─ Step 4: Execute Workflow (Data Export)

Complex process broken into modular steps.

Conditional Workflow Routing

Conditional: checkRequestType
├─ Type A → Execute Workflow (Process Type A)
├─ Type B → Execute Workflow (Process Type B)
└─ Type C → Execute Workflow (Process Type C)

Different workflows for different scenarios.

Parallel Processing

Parallel: processMultiple
├─ Branch 1: Execute Workflow (Validate Email)
├─ Branch 2: Execute Workflow (Validate Phone)
└─ Branch 3: Execute Workflow (Validate Address)

Multiple validation workflows run simultaneously.

Error Handling

If the child workflow fails:

  • The Execute Workflow node fails
  • The onFailure path is triggered (if defined)
  • Error details are available in execution logs

Example Error Handling

Execute Workflow: processPayment
  onSuccess: fulfillOrder
  onFailure: handlePaymentFailure

handlePaymentFailure:
└─ Function: logError
   └─ Conditional: checkRetryable
      ├─ Retryable → retryPayment
      └─ Not Retryable → refundCustomer

Limitations

  • Published Only: Can only execute published workflows
  • Same Organization: Must be in the same organization
  • Synchronous: Parent waits for child to complete
  • No Recursion: Workflows cannot call themselves (directly or indirectly)
  • Version Coupling: Changes to child workflows immediately affect parents
  • Execution Time: Child workflow time counts toward parent’s total execution time

Workflow Composition Benefits

  • Reusability: Write once, use in multiple workflows
  • Maintainability: Update logic in one place
  • Testing: Test components independently
  • Organization: Keep workflows focused and manageable
  • Collaboration: Different teams can own different workflows
  • Versioning: Update child workflows without changing parent structure

Performance Considerations

  • Execution Time: Each child workflow adds to total execution time
  • Nesting Depth: Deeply nested workflows take longer to execute
  • Parallel Execution: Use Parallel nodes to call multiple workflows concurrently
  • Resource Usage: Multiple workflow executions consume more resources
  • Timeout: Ensure child workflows complete within timeout limits

Example: Complete Modular System

Parent: Order Processing Workflow

receiveOrder
└─ Execute Workflow: Validate Customer
   └─ Conditional: customerValid
      └─ Yes → Parallel: processOrder
         ├─ Execute Workflow: Validate Address
         ├─ Execute Workflow: Check Inventory
         └─ Execute Workflow: Process Payment

         └─ Conditional: allSucceeded
            └─ Yes → Execute Workflow: Fulfill Order
               └─ Execute Workflow: Send Confirmation
                  └─ Set Output: orderComplete

This modular approach uses 6 specialized workflows that can be reused, tested, and maintained independently.

Child Workflow Requirements

For a workflow to be called by Execute Workflow:

  1. Must Be Published: Workflow must be published (have a stateMachineArn)
  2. Input Schema: Define trigger schema for input parameters
  3. Output Schema: Use Set Output node(s) to define return data
  4. Same Organization: Must be in the same organization as parent

Accessing Child Workflow Data

The parent workflow can access all data from the child workflow’s Set Output node:

// If child workflow's Set Output has:
{
  user: { id: "123", name: "John" },
  orders: [...],
  totalSpent: 1234.56
}

// Access in parent workflow:
$.results.<nodeId>.user.id         // "123"
$.results.<nodeId>.user.name       // "John"
$.results.<nodeId>.orders          // array
$.results.<nodeId>.totalSpent      // 1234.56

This direct access makes it easy to use child workflow results in subsequent nodes.