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

# Sub-steps

> These are used for tracking smaller unit of work in a business process eg conditional logics, sub-functional logic, etc.

Sub-steps can only be recorded under a step, meaning you need to have created a step object to add a sub-step to it.

**Note:** You cannot create a sub-step once the step has been marked as successful or failed.

#### When to Use

* **Complex operations** - Break down multiple distinct actions within one step
* **Debugging visibility** - Track intermediate progress for troubleshooting
* **Performance analysis** - Identify bottlenecks within step execution

### Example

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    // Track granular operations within a step
    const paymentStep = thread.step('payment_processed');

    try {
      paymentStep.subStep('validate_card', { cardType: 'visa' }, 'success');
      paymentStep.subStep('check_fraud', { fraudScore: 0.15 }, 'success');
      paymentStep.subStep('authorize_payment', { authCode: 'AUTH-123' }, 'success');
      
      await paymentStep
        .addContext({ totalAmount: 299.99 })
        .success();
        
    } catch (error) {
      paymentStep.subStep('error_handler', { error: error.message }, 'failed');
      await paymentStep.failed({ message: 'Payment failed' });
    }
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    // Track granular operations within a step
    paymentStep := thread.Step("payment_processed")

    err := processPayment()
    if err != nil {
        paymentStep.SubStep("error_handler", map[string]any{"error": err.Error()}, "failed")
        _, stepErr := paymentStep.Failed(ctx, map[string]any{"message": "Payment failed"})
        if stepErr != nil {
            log.Fatal(stepErr)
        }
        return
    }

    paymentStep.SubStep("validate_card", map[string]any{"cardType": "visa"}, "success")
    paymentStep.SubStep("check_fraud", map[string]any{"fraudScore": 0.15}, "success")
    paymentStep.SubStep("authorize_payment", map[string]any{"authCode": "AUTH-123"}, "success")

    _, err = paymentStep.
        AddContext(map[string]any{"totalAmount": 299.99}).
        Success(ctx)
    if err != nil {
        log.Fatal(err)
    }
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    # Track granular operations within a step
    payment_step = thread.step("payment_processed")

    try:
        payment_step.sub_step("validate_card", {"cardType": "visa"}, "success")
        payment_step.sub_step("check_fraud", {"fraudScore": 0.15}, "success")
        payment_step.sub_step("authorize_payment", {"authCode": "AUTH-123"}, "success")

        await payment_step.add_context({"totalAmount": 299.99}).success()
    except Exception as error:
        payment_step.sub_step("error_handler", {"error": str(error)}, "failed")
        await payment_step.failed({"message": "Payment failed"})
    ```
  </Tab>
</Tabs>

#### Properties

<Tabs>
  <Tab title="JavaScript">
    | Parameter | Type   | Required | Default     | Description                      |
    | --------- | ------ | -------- | ----------- | -------------------------------- |
    | `name`    | string | Yes      | -           | Sub-step identifier              |
    | `context` | object | No       | `{}`        | Additional data for the sub-step |
    | `status`  | string | No       | `'success'` | Either `'success'` or `'failed'` |
  </Tab>

  <Tab title="Go">
    | Parameter | Type            | Required | Default     | Description                      |
    | --------- | --------------- | -------- | ----------- | -------------------------------- |
    | `name`    | string          | Yes      | -           | Sub-step identifier              |
    | `context` | map\[string]any | No       | `nil`       | Additional data for the sub-step |
    | `status`  | string          | No       | `"success"` | Either `"success"` or `"failed"` |
  </Tab>

  <Tab title="Python">
    | Parameter | Type   | Required | Default     | Description                      |
    | --------- | ------ | -------- | ----------- | -------------------------------- |
    | `name`    | string | Yes      | -           | Sub-step identifier              |
    | `context` | dict   | No       | `{}`        | Additional data for the sub-step |
    | `status`  | string | No       | `'success'` | Either `'success'` or `'failed'` |
  </Tab>
</Tabs>

#### Key Differences from Steps

**Scope** - Steps operate at the thread level, while sub-steps are contained within a step.

**Validation** - Steps are subject to contract rules and validation, whereas sub-steps have no validation applied.

**Notifications** - Steps trigger events and notifications, but sub-steps do not emit any events.
