> ## Documentation Index
> Fetch the complete documentation index at: https://docs.jinba.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Step Module Options

> Learn how to use advanced step options like loops (forEach), conditions (when), and dependencies (needs) in your workflows

## Overview

Each step in a Jinba Flow can be configured with advanced options that control how and when it executes. These options allow you to create sophisticated workflows with conditional logic, loops, and complex dependencies.

## Step Dependencies (needs)

The `needs` option specifies which steps must complete before the current step can run. This creates an execution order and ensures data is available when needed.

### Basic Usage

```yaml theme={null}
- id: analyze_data
  tool: PYTHON_SANDBOX_RUN
  needs:
    - fetch_data
    - validate_input
  input:
    - name: code
      value: "process({{steps.fetch_data.result}})"
```

### Key Points

* **Execution Order**: Steps with `needs` wait for all specified dependencies to complete
* **Parallel Execution**: Steps without dependencies run in parallel automatically
* **Failure Handling**: If a dependency fails or is skipped, dependent steps are also skipped
* **Diamond Patterns**: Complex dependency graphs are supported (A→B, A→C, B→D, C→D)

### Example: Multi-Branch Workflow

```yaml theme={null}
- id: input_data
  tool: INPUT_JSON
  input:
    - name: value
      value: "[1, 2, 3, 4, 5]"

- id: process_even
  tool: PYTHON_SANDBOX_RUN
  needs:
    - input_data
  input:
    - name: code
      value: |
        data = {{steps.input_data.result}}
        result = [x for x in data if x % 2 == 0]

- id: process_odd
  tool: PYTHON_SANDBOX_RUN
  needs:
    - input_data
  input:
    - name: code
      value: |
        data = {{steps.input_data.result}}
        result = [x for x in data if x % 2 != 0]

- id: combine_results
  tool: PYTHON_SANDBOX_RUN
  needs:
    - process_even
    - process_odd
  input:
    - name: code
      value: |
        even = {{steps.process_even.result}}
        odd = {{steps.process_odd.result}}
        result = {"even": even, "odd": odd}
```

## Conditional Execution (when)

The `when` option allows a step to execute only if a specified condition is true. This enables dynamic workflow behavior based on previous step results.

### Basic Syntax

```yaml theme={null}
- id: conditional_step
  tool: TOOL_NAME
  when: "<condition_expression>"
  input:
    - name: param
      value: "value"
```

### Condition Expressions

Conditions support:

* **String Comparison**: `"{{steps.check.result.status}}" == "success"`
* **Numeric Comparison**: `{{steps.count.result}} > 5`
* **Boolean Evaluation**: `{{steps.validate.result.isValid}} == true`

### Example: Conditional Branching

```yaml theme={null}
- id: check_type
  tool: PYTHON_SANDBOX_RUN
  input:
    - name: code
      value: |
        result = {"type": "premium"}

- id: premium_processing
  tool: PYTHON_SANDBOX_RUN
  when: "'{{steps.check_type.result.type}}' == 'premium'"
  needs:
    - check_type
  input:
    - name: code
      value: |
        result = "Processing premium user..."

- id: standard_processing
  tool: PYTHON_SANDBOX_RUN
  when: "'{{steps.check_type.result.type}}' == 'standard'"
  needs:
    - check_type
  input:
    - name: code
      value: |
        result = "Processing standard user..."
```

### Important Notes

* Conditions are evaluated **before** step execution
* If the condition is false, the step status becomes `skipped`
* Skipped steps don't affect downstream steps that depend on them (they will also be skipped)
* Use single quotes around template variables in string comparisons

## Loop Execution (forEach)

The `forEach` option executes a step multiple times, once for each item in a collection. This is useful for batch processing lists of data.

### Basic Syntax

```yaml theme={null}
- id: process_items
  tool: TOOL_NAME
  forEach: "{{steps.get_list.result}}"
  input:
    - name: item
      value: "{{item}}"
```

### How It Works

1. The `forEach` value is evaluated to get a list/array
2. The step executes once for each item in the list
3. Inside the step, `{{item}}` refers to the current item
4. Results are collected as an array

### Example: Processing Multiple Items

```yaml theme={null}
- id: get_users
  tool: INPUT_JSON
  input:
    - name: value
      value: |
        [
          {"id": 1, "name": "Alice"},
          {"id": 2, "name": "Bob"},
          {"id": 3, "name": "Charlie"}
        ]

- id: greet_users
  tool: PYTHON_SANDBOX_RUN
  forEach: "{{steps.get_users.result}}"
  needs:
    - get_users
  input:
    - name: code
      value: |
        user = {{item}}
        result = f"Hello, {user['name']}!"

- id: combine_greetings
  tool: PYTHON_SANDBOX_RUN
  needs:
    - greet_users
  input:
    - name: code
      value: |
        greetings = {{steps.greet_users.result}}
        result = "\n".join([g['result'] for g in greetings])
```

### Accessing Item Properties

```yaml theme={null}
forEach: "{{steps.items.result}}"
input:
  - name: id
    value: "{{item.id}}"
  - name: name
    value: "{{item.name}}"
```

### forEach with Index

If you need the index of the current item, you can use Jinja2 loops in the input:

```yaml theme={null}
- id: process_with_index
  tool: PYTHON_SANDBOX_RUN
  input:
    - name: code
      value: |
        items = {{steps.get_items.result}}
        results = []
        {%- for item in items %}
        results.append({"index": {{loop.index}}, "value": "{{item}}"})
        {%- endfor %}
        result = results
```

## Combining Options

You can combine `needs`, `when`, and `forEach` in a single step:

```yaml theme={null}
- id: process_active_items
  tool: PYTHON_SANDBOX_RUN
  needs:
    - get_items
    - check_enabled
  when: "{{steps.check_enabled.result.active}} == true"
  forEach: "{{steps.get_items.result}}"
  input:
    - name: code
      value: |
        item = {{item}}
        result = f"Processed: {item}"
```

**Evaluation Order**:

1. Wait for all `needs` dependencies to complete
2. Check if `when` condition is true
3. If true, execute `forEach` loop (or single execution if no forEach)

## Best Practices

### Dependencies

* Keep dependency chains shallow when possible
* Use parallel execution to improve performance
* Clearly name steps to make dependencies readable

### Conditions

* Use meaningful condition expressions
* Consider all possible outcomes (success, failure, edge cases)
* Test conditions with various input values

### Loops

* Limit loop iterations to avoid long execution times
* Handle empty arrays gracefully
* Consider memory usage for large datasets

## Related

* [YAML Coding Panel](/en/pages/basics/manifest) - Complete YAML syntax reference
* [Variables & Templates](/en/pages/basics/variables) - Variable placeholders and Jinja2 templates
* [Debug](/en/pages/basics/debug) - Debugging workflow execution
