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

# Troubleshooting

> What to check when a run doesn't start, doesn't reach your app, or doesn't go on.

Most problems show on the run's page: its status, its error, and its last step tell you where it stopped. Find the symptom below, and the fix that goes with it.

## Your endpoint

### Runs fail with `deliveryFailed`

Nelkap called your endpoint three times, over about three minutes, without a `2xx` answer. Check, in this order:

1. The project's endpoint is the exact URL of your route, with `https://` and the full path.
2. Your app is deployed and running at that URL.
3. `NELKAP_SECRET` in this environment is the secret of this project. A staging secret in production, or an old secret after a rotation, gets a `401`.
4. Nothing answers before `handle`: a sign-in check, a middleware, a redirect, or your host's own protection, like Vercel's [Deployment Protection](https://docs.nelkap.com/deploy/vercel.md#deployment-protection).
5. Your app registers the workflow. If it doesn't know the workflow, `handle` answers `404`.

Once it's fixed, [replay](https://docs.nelkap.com/monitor/runs.md#replay-a-run) the runs that failed.

### Check your endpoint from a terminal

Send your endpoint a call with your secret:

```bash theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
curl -X POST https://your-app.com/api/nelkap \
  -H "Authorization: Bearer $NELKAP_SECRET" \
  -H "Content-Type: application/json" \
  -d '{}'
```

The call names no workflow, so nothing runs. The answer tells you how far it got:

| Answer | What it means |
| - | - |
| `404` with `{"error":"workflowNotFound"}` | Your route works, and the secret matches. |
| `401` with `{"error":"secretInvalid"}` | The route works, but the secret doesn't match `NELKAP_SECRET`. |
| Anything else | Something other than `handle` answered: check the URL, your middleware, and your host. |

## Starting runs

### `run` throws "Only a workflow passed to registerWorkflows can start a run."

The function you passed to `run` isn't in the list given to `registerWorkflows` on this client. Add it to the list, and make sure the code that starts the run imports the same client as your route. See [Create your client](https://docs.nelkap.com/installation.md#create-your-client).

### `run` throws `workflowNotFound`

Nelkap has no enabled workflow with this name in the project of your API key. Check that:

* `NELKAP_API_KEY` belongs to the project you're looking at, not to another environment.
* The workflow is in the list every instance of your app registers. An instance that registers a list without it turns it off.

### `apiKeyMissing`, `apiKeyInvalid`, or `ipNotAllowed`

* `apiKeyMissing`: `NELKAP_API_KEY` is empty in this environment.
* `apiKeyInvalid`: the key was deleted, has expired, or was copied wrong.
* `ipNotAllowed`: the key only takes requests from its allowed IPs. Serverless hosts often send requests from changing addresses: leave the list empty there, unless your host gives you fixed ones.

See [API keys and secrets](https://docs.nelkap.com/manage/api-keys.md).

### `throughputLimitReached`

Your workspace sent more requests in one second than your plan allows. Try the call again a moment later. Inside a run, a step that gets this answer isn't lost: the run picks up again about five minutes later. See [Limits](https://docs.nelkap.com/limits.md#by-plan).

### A run stays Pending

A run goes to your app within a minute of being due. If it stays Pending longer, it's waiting its turn: its workflow, or your workspace, already has as many runs going as its limit allows. It starts as soon as one of them ends. See [Limit concurrency](https://docs.nelkap.com/guides/concurrency.md).

## Inside a run

### "nelkap.step can only be called while Nelkap runs a workflow."

A step was called outside a run. This happens when your code calls a workflow function directly, like `await onboardUser(id)`. Start it with `nelkap.run(onboardUser, id)` instead, and Nelkap runs it.

### A step ran twice

A step cut off before its result was saved runs again when the run picks up, for example after a crash or a deploy. Make that harmless with an idempotency key, or check before you act. See [Make steps safe to run twice](https://docs.nelkap.com/guides/idempotency.md).

### A step's result has changed shape

Results are saved as JSON: a `Date` comes back as a string, and `undefined` as `null`. Return plain values, and turn them back into what you need after the step. See [Steps](https://docs.nelkap.com/concepts/steps.md#step-results-are-saved-as-json).

### A run fails with `stepLimitReached`

The run reached 100 steps, or 32 MB of saved steps. Put more work in each step, return less from each one, or split the job across runs. See [Loops and parallel steps](https://docs.nelkap.com/guides/loops.md).

### A run stopped in the middle

If a run shows Running but its app stopped, through a crash, a deploy, or a host time limit, Nelkap calls your app again about five minutes later, and the run picks up from its last saved step. You have nothing to do. See [Crashes and short outages](https://docs.nelkap.com/guides/failures.md#crashes-and-short-outages).

## Pauses and schedules

### A run waits and never wakes

An event wakes only the runs already waiting on its key when it arrives. Check that:

* The run reached its `step.wait` before the event was emitted. Its page shows Waiting, with its key.
* The event's `wakeOn` is exactly the key of the wait.
* The event was emitted in the run's project.

To wake it now, emit the event again with its key. See [Wait for an event](https://docs.nelkap.com/guides/wait.md).

### A run sleeps a little longer than asked

Nelkap wakes sleeping runs every minute, so a run goes on within a minute after its time. See [Sleep](https://docs.nelkap.com/guides/sleep.md#when-the-run-wakes-up).

### A schedule doesn't start at the time you expect

* Schedules are in UTC. `0 9 * * *` is 9:00 UTC, not 9:00 where you are.
* A new or changed schedule applies once your app has registered it. On a serverless host, your app starts with the first request it gets after a deploy: start a run or emit an event from the new deploy to send your list right away. See [Register your workflows on every start](https://docs.nelkap.com/deploy/overview.md#register-your-workflows-on-every-start).

See [Schedules](https://docs.nelkap.com/triggers/schedules.md).


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