Docs / Strand / templating/nested-workflows

Nested Workflows

Call workflows from other workflows to create modular, reusable designs.

Flow Call Node

The Flow Call node executes another workflow as a step in your current workflow.

Configuration

flow_id (required)

data (optional)

Example Configuration

Direct connection:

json

{
  "flow_id": "process-user",
  "data": {
    "user_id": "{{ payload.id }}",
    "context": {
      "source_workflow": "{{ meta.workflow_id }}",
      "timestamp": "{{ meta.received_at }}"
    }
  }
}

Non-direct access:

json

{
  "flow_id": "process-user",
  "data": {
    "user_id": "{{ steps.user_lookup.output_payload.id }}",
    "context": {
      "source_workflow": "{{ meta.workflow_id }}",
      "timestamp": "{{ meta.received_at }}"
    }
  }
}

Passing Data

Default Behavior

If you don't specify data, the current event is passed:

json

{
  "payload": { /* current payload */ },
  "meta": { /* current meta */ }
}

Custom Data

Pass a custom object with templating:

Direct connection:

json

{
  "user_id": "{{ payload.id }}",
  "processed_data": {{ payload | tojson }}
}

Non-direct access:

json

{
  "user_id": "{{ steps.user_lookup.output_payload.id }}",
  "processed_data": {{ steps.process.output_payload | tojson }}
}

Accessing Output

The nested workflow's output is available through the Flow Call node:

jinja

{{ steps.flow_call_node.output_payload }}
{{ steps.flow_call_node.output_payload.result }}

Infinite Loop Prevention

Strand automatically prevents infinite loops by tracking the call chain.

How It Works

  1. System tracks which workflows are in the current call chain
  2. Before executing a nested workflow, checks if it's already in the chain
  3. If detected, raises an error with the full call chain

Error Example

code

Infinite loop detected: workflow 'workflow-a' is calling itself
(directly or indirectly).
Call chain: workflow-a -> workflow-b -> workflow-a

Best Practices

1

Design hierarchy

Plan workflow dependencies before building

2

Single responsibility

Each workflow should do one thing well

3

Document dependencies

Note which workflows call which others

4

Test incrementally

Test nested workflows individually

Use Cases

Modular Processing

Break complex workflows into smaller pieces:

Reusable Components

Create reusable workflow components:

Conditional Execution

Call different workflows based on conditions:

jinja

{% if payload.type == 'user' %}
  process-user-workflow
{% else %}
  process-admin-workflow
{% endif %}