# Recover a failed run

> Retry a failed run from the step that failed, and resolve external calls whose outcome Hodoflow could not record.

A failed run keeps everything it already did. Recovery means re-running the
part that never finished, not starting again from the beginning.

## Outcome

The run reaches completion, or you know exactly which step is blocking it and
why.

## Before you start

Open the run from **Workflows → Monitor** and find the first step with status
**failed**. Read its **Error**. Everything below depends on knowing whether the
failure was transient or a configuration problem.

## 1. Decide what kind of failure it was

| The error says | It is | Do this |
|---|---|---|
| A timeout, `503`, `502`, connection refused | Transient | Retry the run. |
| `401`, `403` | A credential problem | Fix the connector or service account, then retry. |
| `404`, `422` | Usually a configuration problem | Fix the workflow, save, activate, then retry. |
| A formula or mapping error | A configuration problem | Fix it, save, activate, then retry. |

Retrying a configuration problem without fixing it reproduces the same failure.

## 2. Retry from the failure

A failed run shows a **Run again from the failure** panel with a **Retry Run**
button. The text beneath it names what will re-run — the failed step and what
follows it.

Every step that finished is kept. Only the steps that never finished run again,
so a run that fetched, transformed, and then failed to write does not fetch
twice.

**Checkpoint:** the run's status changes from **failed**, and the steps that
had already completed keep their original durations.

## 3. Resolve calls whose outcome is unknown

Occasionally a run stops between issuing an external call and recording what
came back. Hodoflow cannot know whether that call went through, so it will not
guess.

The run then shows an **Unaccounted-for external calls** panel above the retry:

> This run stopped between issuing a call and recording what it returned. Check
> the provider and say what happened — running the step again is only safe once
> you have.

Each unresolved call is listed with its step and a key identifying it. For each
one:

- **Never sent** — the provider has no record of it. The step is free to run
  again.
- **Went through** — the provider did receive it. The failure is kept rather
  than repeating the call.

A call the engine already knows is safe to repeat is marked **Safe to repeat**
and needs no answer from you.

**Retry Run** stays disabled until every listed call has an answer. That is
deliberate: repeating a payment or an order is worse than a stuck run.

**Checkpoint:** the panel is empty and **Retry Run** is enabled.

## 4. Stop it happening again

- Set a retry policy on steps that call flaky endpoints, so a blip never
  reaches this page. See [Retries](/help/workflows/retries).
- Set **Max Retries** to `0` on a step that writes something the endpoint would
  count twice, so a blip never turns into a duplicate.
- Add an [on-error path](/help/workflows/error-and-compensation) to be told
  when something fails, rather than finding out from this page.

## Common problems

**Retry Run is greyed out.** There are unresolved external calls above it.
Answer each one.

**The retry failed at the same step.** The cause was not transient. Fix the
workflow, save, activate the new version, and retry again — the retry uses the
version the run was pinned to, so a fix has to be activated to take effect on
new runs.

**I answered `Went through` and the run is still failed.** That is the intended
outcome: the call is not repeated, so the run stays failed. Handle the
remainder by hand, or start a fresh run once the state is consistent.

**The run has no retry panel.** Only failed runs get one. A `suspended` run is
still going.

## Next step

[Watch runs in Monitor](/help/run-troubleshoot/monitor-runs), or [Retries](/help/workflows/retries)
to reduce how often you end up here.
