---
url: 'https://adk.nht.io/the-loop/llm-dispatch/errors.md'
description: >-
  How executor throws, middleware throws, abort, and ctx.nack each surface — and
  how surfacing depends on the entry point.
---

# Errors during dispatch

How the four error sources during a dispatch reach their terminal state, and why the surfacing differs depending on whether `dispatch()` was called by a [`TurnRunner`](https://adk.nht.io/api/@nhtio/adk/turn_runner/classes/TurnRunner) or standalone.

[LLM Dispatch](../llm-dispatch) covers the dispatch contract; the [Exception Reference](/api/@nhtio/adk/exceptions/) lists every dispatch-specific `E_*` code under **Dispatch**.

## Error sources

* **Executor throws (non-abort).** Wrapped as `E_LLM_EXECUTION_EXECUTOR_ERROR`, emitted on `error`, the pending delta queue is cleared, the dispatch nacks.
* **Input or output middleware throws (non-abort).** Both pipelines surface their failures through the same code, `E_DISPATCH_PIPELINE_ERROR`. Emitted on `error`, the dispatch nacks. (The summary names "input pipeline" and "output pipeline" are not encoded in the exception itself — observers identify the side via `iterationStart` / `iterationEnd` framing or via a label inside the middleware.)
* **Abort.** The `AbortSignal` fires (turn-level abort, gate-aborted, or whatever else is wired into the controller). The delta queue is discarded, the loop breaks, `dispatchEnd.status` is `'aborted'`. No `error` event is emitted — abort is not an error.
* **`ctx.nack(error)` called.** `dispatchEnd.status` is `'nack'`, `dispatchEnd.error` is the supplied error.

::: warning Where errors surface depends on the entry point
When `TurnRunner.run()` is the caller, dispatch errors are caught by the runner, emitted on the `error` bus, and `run()` still resolves. When `dispatch()` is called standalone, the same errors **reject the `dispatch()` promise** — no [`TurnRunner`](https://adk.nht.io/api/@nhtio/adk/turn_runner/classes/TurnRunner) is there to swallow them. Wire your own try/catch around standalone dispatches, or rely on the observability hooks you passed in.
:::

See the [Exception Reference](/api/@nhtio/adk/exceptions/) for the exception codes and what each one means about which seam misbehaved.
