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

# Recovering a Blocked Run

> What BLOCKED means, how to find the cause, and which recovery action applies to each one.

A run moves to `BLOCKED` when it hits something it cannot get past on its own. `BLOCKED` is **not terminal** — almost every cause is recoverable, but the right recovery depends on the cause.

<Info>
  **Start with `last_error`.** Fetch the run with [Get Run](/v1/api/runs/get) and read `last_error.error_label`, plus `params.appendix` when the label is `LIMIT_REACHED`. Everything below keys off those two fields.
</Info>

## Find the cause

```bash theme={null}
curl "https://api.edges.run/v1/runs/{run_uid}" \
  -H "X-API-Key: <YOUR_API_KEY>"
```

The response carries `status`, `last_error`, `retry_count` and `postponed_until`. When `postponed_until` is set, Edges has already scheduled the retry for you — see below.

## Cause → recovery

| `error_label` | What happened | What to do |
| - | - | - |
| `LIMIT_REACHED` | An identity or LinkedIn limit was hit. `params.appendix` says which window | **Wait for the window to reset**, then resume. Check `postponed_until` first — it may already be handled. See [I hit a limit](#i-hit-a-limit) below |
| `LK_BAD_COOKIE` · `MISSING_COOKIE` · `RLS_BAD_COOKIE` | The stored LinkedIn session is no longer valid | **Reconnect the integration first**, then resume. Resuming without reconnecting will block again immediately |
| `LK_LOGIN_ERROR` · `SN_LOGIN_ERROR` · `RLS_LOGIN_ERROR` | Login failed for the identity | Reconnect the integration. If it recurs, the account may be in a checkpoint — see [Checkpoint](/v1/api/linkedin/checkpoint) |
| `NO_VALID_ACCOUNT_CONFIGURED` | No identity in the workspace could run the action | Check the identity exists, is connected, and matches the `identity_mode` you passed |
| `LK_ACCOUNT_UPGRADE` · `SN_ACCOUNT_UPGRADE` · `LR_ACCOUNT_UPGRADE` | The action needs a licence the account doesn't have | Upgrade the LinkedIn account, or route the action to an identity that has the licence |
| `PROXY_ERROR` | The identity's proxy failed | Retryable. Wait for `postponed_until` if present, otherwise wait a minute and resume |
| `STATUS_429` | LinkedIn rate-limited the request directly, with no Edges guardrail in front of it | Back off with an exponential delay before resuming. Do not retry immediately |
| `API_TIMEOUT_ERROR` · `HTTP_ERROR` | Transient transport failure | Resume; these usually succeed on a second attempt |
| `BAD_INPUT` · `BAD_PARAMETERS` · `MISSING_PARAMETER` | The request itself is wrong | Resuming will not help. Fix the input and launch a new run |

<Warning>
  For anything cookie- or login-related, **reconnect before you resume**. Resuming a run whose identity is still invalid consumes a retry and blocks again.
</Warning>

## Resume the run

```bash theme={null}
curl -X POST "https://api.edges.run/v1/runs/{run_uid}/resume" \
  -H "X-API-Key: <YOUR_API_KEY>"
```

Resuming a `BLOCKED` run:

* sets the run back to `SCHEDULED`
* clears `last_error`
* resets `retry_count` to **0**
* clears `postponed_until`
* moves every `BLOCKED` **input** in that run back to `SCHEDULED`

So a resumed run gets a full fresh set of retries, and inputs that failed are attempted again. Inputs that already succeeded are not re-run.

<Note>
  A run that belongs to a flow run cannot be resumed on its own — the API returns `422`. Resume the flow run instead.
</Note>

## Resume vs. continue

These are different operations and are not interchangeable.

| | Resume | Continue |
| - | - | - |
| **Endpoint** | [`POST /runs/{run_uid}/resume`](/v1/api/runs/manage) | [`POST /runs/{run_uid}/continue`](/v1/api/runs/continue) |
| **Purpose** | Retry what failed | Fetch data that is new since the last retrieval |
| **Use when** | The run is `BLOCKED` and you fixed the cause | The run finished and you want the delta |
| **Requires** | — | `sync_mode: "incremental"` and an [Engagement Identity](/v1/identities/engagement) |
| **Valid statuses** | `BLOCKED` only — anything else returns `400` | `BLOCKED`, `STOPPED`, `FAILED`, `PARTIAL_SUCCEEDED`, `SUCCEEDED` |

## I hit a limit

When `error_label` is `LIMIT_REACHED`, `params.appendix` tells you which window was exhausted and therefore how long to wait:

| `params.appendix` | `params.timespan` | Wait until |
| - | - | - |
| `MINUTE_LIMIT` | Minute | The next minute |
| `15M_LIMIT` | 15 minutes | The 15-minute window rolls |
| `HOURLY_LIMIT` | Hour | The hour rolls |
| `4H_LIMIT` | 4 hours | The 4-hour window rolls |
| `DAILY_LIMIT` | Daily | The 24-hour window rolls |
| `LONG_PERIOD_LIMIT` | Long period | The long window rolls — InMail uses \~31 days |
| `IDENTITY_RATE_LIMIT` | *(varies)* | Every identity available for the action is exhausted. Wait, or add capacity |
| `API_RATE_LIMIT` | Minute | LinkedIn's own per-minute protection tripped. Back off |
| `API_FUSE_LIMIT` | Daily | LinkedIn's own daily protection tripped. Back off until the next day |

<Tip>
  All limits use **rolling windows**, not calendar ones — a daily limit resets 24 hours after the calls that consumed it, not at midnight. If `postponed_until` is present, use it rather than computing the wait yourself.
</Tip>

If the identity was connected in the last few days, check [Identity Ramp-Up](/v1/limits/identity-ramp-up) before assuming the quota table applies.

## Related

<CardGroup cols={3}>
  <Card title="Manage Runs" icon="sliders" href="/v1/runs/manage">
    The full run lifecycle and status list.
  </Card>

  <Card title="Error Reference" icon="triangle-exclamation" href="/v1/error-reference">
    Every error label and what to do about it.
  </Card>

  <Card title="Rate Limits" icon="gauge-high" href="/v1/runs/rate-limits">
    Workspace and plan limits.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.