> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.runtype.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.runtype.com/_mcp/server.

# Debugging flows

Use test runs, execution logs, and step inspection to find and fix Flow errors.

## Test a Flow

Use a test run to reproduce a problem with controlled inputs. The test uses the
current unsaved steps, so you can test a change before you save the Flow.

To test a Flow, follow these steps:

1. In the Flow editor toolbar, click **Run flow**. The **Run Flow** sheet opens.
2. In the **Run Flow** sheet, choose **Test**.
3. In the **Test** view, enter the input values for the Flow.
4. Click **Run Flow**. The execution results appear in the sheet.
5. Review each step's input, output, status, and execution time when available.

The **Test** view runs in debug mode by default. Debug mode shows the output of
hidden steps, which are steps whose output is not streamed to the caller. To see
only what a caller of the Flow receives, choose **Run in user mode** in the execution
mode menu next to **Run Flow**.

Runtype saves each test run with its step logs, so the run appears in **Logs** like
any other run. When you open the Flow inside a Product, the Flow's run list marks the
run with a **Dashboard** badge.

After the run completes, click **Save as test case**. Review the input and expected
answer in the dialog, then click **Save case**. The dashboard creates the Flow's
default eval suite if it does not exist.

## Retest one step

After you change a step, retest that step alone instead of running the whole Flow
again. The step reruns with your current configuration, including unsaved edits,
against the resolved inputs from the previous run. The result is not saved to
your run history.

To retest a step, follow these steps:

1. Run the whole Flow once. The **Test step with last run** action is unavailable
   until the Flow has a previous run.
2. In the Flow editor, edit the step configuration.
3. Hover over the step, then click **Test step with last run**. The **Test step**
   sheet opens and shows the step's **Previous output**.
4. Click **Run test**. The result appears under **New output**.
5. Optional: To test the same configuration again, click **Run again**.

If the step writes records, sends a message, or calls an external service, the
dashboard asks you to confirm before it runs the step. Conditional, set-variable,
and paginate-api steps do not have the **Test step with last run** action.

## Inspect execution logs

Use the **Logs** page to inspect completed and failed Flow executions. To inspect
an execution, follow these steps:

1. Open **Logs** in the sidebar.
2. Use the search field or filters to find the Flow execution.
3. Select the execution.

The execution details include the following information:

* A timeline with each step's status and duration.
* A step inspector with the step's input, output, and configuration.
* Error messages and stack traces when they are recorded.
* Variable values from the execution when they are recorded.

If the execution shows **Verbose logging off.**, Runtype did not store token counts,
cost, or full outputs for that run. To capture them, set **Verbose logging** to
**On** in the surface settings, or set the `loggingPolicy` dispatch option to `on`.
Then reproduce the problem.

For more information, see [Working with logs](/user-guide/logs/working-with-logs).

## Inspect step results

Use the execution results to compare what each step received with what it returned.
Select a step to review its input, output, duration, and status. This comparison
helps you identify the step that fails or produces unexpected output.

## Debug from code

When you run a Flow from the API, set `options.debugMode` to `true` in the dispatch
request. The response stream then includes events for hidden steps. The default is
`false`.

**`cURL`**

```bash title="cURL"
curl https://api.runtype.com/v1/dispatch \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "flow": { "id": "YOUR_FLOW_ID" },
    "inputs": { "customerId": "cus_123" },
    "options": { "recordMode": "virtual", "debugMode": true }
  }'
```

Replace `YOUR_API_KEY` and `YOUR_FLOW_ID` with your values. For all request options,
see the [dispatch endpoint reference](/api-reference/runtype-api/dispatch/execute-a-flow-or-agent).

From the Runtype CLI, list a Flow's failed runs or stream its live logs:

```bash
runtype logs list --flow YOUR_FLOW_ID --status failed
runtype tail --flow YOUR_FLOW_ID
```

From an MCP client connected to the
[Runtype MCP server](/developer-guides/integrations/runtype-mcp-server), use the
`get_flow_step_results` tool for per-step results and the `trace_execution` tool for
the trace of one execution.

## Resolve common errors

Use these checks to diagnose common Flow errors.

### Later steps receive empty values

A Flow can complete while a step inside it failed. Most steps use **Continue on
error** by default, which a narrow step card shortens to **Ignore errors**. The failed step
writes its default value, or `null`, to its output variable, and the Flow continues.

To find and stop the failure, follow these steps:

1. In the execution results, select the step that produces the empty value.
2. Review the step's error message.
3. On the step card, open the error-handling control and choose **Stop on error**.
   The Flow now stops when the step fails.

For the other error-handling modes, see [Error handling](/user-guide/flows/creating-and-editing-flows#error-handling).

### Undefined variable

A reference to a step output that does not exist fails in different ways:

* In transform-data code, the step reports
  `Cannot read properties of undefined (reading 'output')`.
* In a template, the `{{name}}` placeholder stays in the text unchanged.

In both cases, check the spelling of the `outputVariable` and confirm that its step
runs before the reference.

### API call failure

If a step reports `HTTP 401: Unauthorized`, verify the endpoint, the request headers,
and the credentials. Store credentials as secrets and reference them with
`{{secret:NAME}}`, then confirm that the secret exists. Check the external service's
authentication requirements before you run the Flow again.

### Timeout

A timed-out step reports that it `exceeded step timeout` or `exceeded flow deadline`.
To resolve a timeout, follow these steps:

1. In **Logs**, find the step that timed out and compare its duration with the
   timeout that applies.
2. Reduce the work in the step, or raise the step timeout, the Flow timeout, or
   both.

The Flow timeout also bounds each step, so a 5-minute step inside a 1-minute Flow
stops after 1 minute. An `execute-agent` step has a 30-second default timeout. Set
`config.timeout` in milliseconds on the step when the child agent needs longer. The
step timeout still applies, so a `config.timeout` longer than 5 minutes has no effect
unless you also raise `options.stepTimeoutMs` on the dispatch request.

Each timeout measures application wall-clock time, not CPU time, so time spent
waiting for models and tools counts toward it.

For the defaults and accepted ranges, see
[Timeouts and long-running work](/user-guide/flows/timeouts-and-long-running-work).

### Invalid JSON

If an API call request body, or a `JSON.parse` call in a transform-data step, fails
on malformed JSON, validate the JSON syntax. Quote string values and remove trailing
commas before you run the Flow again. To handle a parse failure inside the step, see
[Handle errors](/user-guide/flows/using-transform-data-steps#handle-errors).

## Inspect variable values

Add a transform-data step that returns the variables you want to inspect. Reference
an earlier step by its `outputVariable` name:

```javascript
return {
  logged: true,
  customer_data_value: customer_data,
  total_value: calculate_total,
}
```

Replace `customer_data` and `calculate_total` with the `outputVariable` names in
your Flow. Review the returned values in the execution results.

## Test incrementally

To isolate a failing change, add and test steps in sequence:

1. Add the first step and test the Flow.
2. Add the second step and test the Flow again.
3. Continue until a step changes the result.

Keep complex logic in separate transform-data steps when you need to inspect intermediate values.

## Use default values

Use default values when a variable can be null or undefined. Add fallbacks with `||` or `??`:

```plaintext
{{customer_data.tier || "standard"}}
{{order_history.count || 0}}
```

Replace `customer_data` and `order_history` with the relevant `outputVariable`
names. The `||` operator uses a truthy fallback. The `??` operator uses a fallback
only for `null` or `undefined`.

Test empty inputs, null values, large datasets, and invalid data to cover edge cases.

## Test conditional branches

Run the Flow with inputs that select each branch:

1. Run the Flow with input that makes the condition true.
2. Confirm that the `if` branch runs.
3. Run the Flow with input that makes the condition false.
4. Confirm that the `else` branch runs.

Check that every variable in the condition exists and has the expected type.

## Debug performance

If a Flow takes longer than expected, use execution logs to compare step durations.
To reduce execution time, use these practices:

* Identify the step with the longest duration.
* Choose a model that matches the task's latency needs.
* Reduce prompt length.
* Simplify transform-data steps.
* Remove unnecessary steps.

## Validate inputs

Validate required inputs at the start of a Flow. To stop the Flow when validation
fails, set the transform-data step's error handling to **Stop on error**, then
return a validation result for valid input:

```javascript
if (!customerId) {
  throw new Error('Customer ID is required')
}

return { validated: true }
```

Replace `customerId` with the input variable that your Flow requires. The step
throws an error for missing input and returns `{ validated: true }` for valid
input.

## Next steps

* [Flow validation warnings](/user-guide/flows/flow-validation-warnings): catch reference and configuration errors before you run a Flow
* [Flow execution failures](/user-guide/troubleshooting-faq/flow-execution-failures): diagnose failed executions from Logs
* [Using transform-data steps](/user-guide/flows/using-transform-data-steps): read step outputs and control error handling
* [Timeouts and long-running work](/user-guide/flows/timeouts-and-long-running-work): step and Flow limits
* [Flow variables and templates](/user-guide/flows/flow-variables-and-templates): reference inputs and step outputs
* [Working with logs](/user-guide/logs/working-with-logs): filter and inspect execution history
* [Managing eval suites](/user-guide/evals/managing-eval-suites): organize saved test cases and run evaluations
* [Handling batch failures](/user-guide/flows/handling-batch-failures): troubleshoot record-level failures in batch runs