Skip to navigation

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.

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
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.

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

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, 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.

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.

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.

Inspect variable values

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

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 ??:

{{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:

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