# Handle step errors

import { Steps } from "@astrojs/starlight/components"

By default, when a service step fails (for example a non-2xx HTTP response), Studio stops the run. **On failure** →
**Continue execution** lets later steps run so you can branch with a **Condition** on the step result. Screenshots on
this page use a Shodan host lookup so you can see filled settings and branches.

## When to use

- An API can return a client error (4xx) or empty result that is expected for some inputs, and you still want later
  steps to run.
- You need different paths for a successful response and a known failure (for example notify when a host is missing).
- Prefer [End a flow with Success or Failure](../end-a-flow-with-success-or-failure/) when you fail the run on purpose
  for a business rule, not because a step errored.
- Prefer [Call a flow](../call-a-flow/) **On failure** when the failure comes from a nested flow, not from this step.

Before you begin, open a flow that includes the service step that might fail, with permission to edit it.

## Guide

### Allow the step to fail

**On failure** lives on the step **Settings** tab. **Stop execution** (default) ends the run when the step fails.
**Continue execution** keeps the run going so a later **Condition** can inspect the result.

<ol>
<li>

**Open Settings.** Select the service step (for example an integration that looks up a host), then open the
**Settings** tab.

</li>
<li>

**Set On failure.** Change **On failure** from **Stop execution** to **Continue execution**.
<div class="docs-screenshot-compact">

![Service step Settings with On failure set to Continue execution](./assets/service-step-settings-failure-set-continue.png)

</div>

</li>
</ol>
### Branch on the step result

After the step can fail without stopping the run, add a **Condition** that compares a value from that step—often the
HTTP status code—so each path handles success or failure.

<ol>
<li>

**Add Condition.** Open **Add a step**, choose **Flow**, then **Condition**. Place it after the service step. Rename
it for the rule (for example a status-code check).

</li>
<li>

**Set the rule.** Compare a field from the previous step (for example status code equals `200`) on the pass branch.
Use **else** (or a matching fail rule) for the other path.
<div class="docs-screenshot-compact">

![Condition step that branches on the previous step status code](./assets/condition-step-branches-previous-step-status.png)

</div>

</li>
</ol>
### Handle success and failure paths

On each branch, add the steps that should run when the call succeeded or failed—for example send a notification when
the lookup fails, or continue with the payload when it succeeds.

<ol>
<li>

**Build the success path.** On the branch where the status (or other rule) means success, add the steps that use the
response.

</li>
<li>

**Build the failure path.** On the other branch, add the steps for the expected failure (for example a message that
the resource was not found).
<div class="docs-screenshot-compact">

![Canvas with success and failure branches after a Condition on a Shodan host lookup](./assets/canvas-success-failure-branches-after-condition.png)

</div>

</li>
</ol>
## Example

A security operator looks up a host in Shodan. The flow queries host information for an IP. A previously scanned host
returns status `200` with details; an unscanned host returns a client error.
<div class="docs-screenshot-compact">

![Shodan Host Information step with a successful 200 response for a scanned IP](./assets/shodan-host-information-step-successful-200.png)

</div>
<div class="docs-screenshot-compact">

![Shodan Host Information step with a client-error response when the IP was not scanned](./assets/shodan-host-information-step-client-error.png)

</div>

**On failure** is **Continue execution**. A Condition compares the status code. The success path continues with the
host data; the failure path sends a notification such as “IP not found.”

## Keep in mind

- **Continue execution** alone does not handle the error—you still need a **Condition** (or similar) so later steps do
  not treat a failed response as success.
- Many APIs return 4xx for “not found” or bad input; treat those as expected branches when that matches your job.
- **Call a flow**, **Run script**, and most service steps expose the same **On failure** setting.

## Related

[End a flow with Success or Failure](../end-a-flow-with-success-or-failure/) ·
[Call a flow](../call-a-flow/) ·
[Scripts, errors, and run control](../)
