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

# Troubleshooting: a flow execution that failed

> Read a failed flow run end to end — decode the status and error fields, map the failing node-class to its cause (E.164 input, sender, channel config, template approval, upstream API, condition evaluation), and decide between fix, retry, and escalation.

# Troubleshooting: a flow execution that failed

A published flow shows `failed` or `completed_with_errors`, or one node
inside a run keeps throwing. This page walks you through reading the
execution row, identifying the failing node class, and deciding what to
fix. For the field-by-field reference, see
[Flow Executions](/flows/executions).

## What an execution row tells you

The list row and the single-execution detail each carry a diagnosis
surface:

* **`status`** — which terminal (or in-flight) state the run reached.
  The run-level [status values](/flows/executions#status-values) are
  `running`, `waiting`, `completed`, `completed_with_errors`, `failed`,
  and `timeout`. `completed_with_errors` and `failed` are the two
  failure modes this page covers.
* **`error`** — the last failure message on the run. The convention is
  `Last failed node <node_id>: <message>` — the node id prefix tells you
  where to look, and the message tells you what went wrong.
* **`steps`** — one entry per node that ran, in execution order. Each
  step carries `node_id`, `node_type`, a per-step `status`
  (`completed`, `running`, `failed`, `skipped`, or `pending`), plus the
  recorded `input`, `output`, and per-step `error`. Read the failing
  step's `input` — that is usually where the answer is.

A per-step status of `pending` or `running` is not a failure — it means
the run is parked (a delay node, a send-time schedule) or in progress.

```bash theme={null}
curl -G https://api.orbit.devotel.io/api/v1/flows/executions \
  -H "X-API-Key: dv_live_sk_..." \
  --data-urlencode "flow_id=flow_abc123" \
  --data-urlencode "status=failed"
```

## Common node classes that fail

Node failures cluster into six classes. Match the `error` prefix/message
to one:

| Node class                            | Typical `error`                                                                                 | Cause and fix                                                                                                                                                                                                                            |
| ------------------------------------- | ----------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Bad E.164 in a send node**          | `to must be a valid E.164 phone number`                                                         | The send node's `to` field received a malformed value — often an unformatted national number, a variable that resolved to empty, or data fed in by an inbound event. Fix the upstream mapping or the trigger data.                       |
| **Missing sender**                    | sender assignment message                                                                       | The send node has no sender to draw from — the tenant sender pool is empty, or every sender in it failed eligibility (wrong channel, paused, non-compliant). Add an eligible sender to the pool used by that node.                       |
| **Channel not configured**            | channel/whatsapp/email setup message                                                            | The tenant has not finished setting up the channel the node sends on (e.g. WhatsApp sender not connected, email domain unverified). Complete the channel setup under Settings → Channels before running the flow.                        |
| **Template not approved**             | WhatsApp template message                                                                       | A WhatsApp template node referenced a template that is draft, paused, or rejected on Meta's side. Re-check the template's Meta approval status; only approved templates send.                                                            |
| **Upstream API non-2xx**              | `Webhook returned 5xx` / `AI analyze returned ...`                                              | An HTTP webhook or AI node got a non-2xx from the upstream endpoint, or got an authentication/timeout problem. The platform retries bounded times, then surfaces the last status. Fix the upstream, or handle non-2xx on an error edge.  |
| **Expression / condition evaluation** | `Unterminated string literal`, `Forbidden identifier: <name>`, `Method '<name>' is not allowed` | A condition/branch node's expression could not be tokenized or evaluated inside the sandbox. Fix the expression syntax; avoid method calls outside the allowed `includes` / `startsWith` / `endsWith` set and avoid blocked identifiers. |

A run can also fail at the level guardrails: the run aborts if the flow
isn't `published`, if it has no nodes/edges (`has no definition`),
exceeds the 300s wall-clock (`timeout`), or runs more steps than the
cap (`exceeded maximum of ... steps — possible runaway flow`). Those
are definition-level problems, not node problems.

## Cross-reference the failed node with the flow definition

The trace gives you the `node_id` and `node_type` of the failing step.
Open the flow (Flows → open flow → the editor) and find the node whose
id matches the step's `node_id`. The `node_type` (`sendSms`,
`sendWhatsapp`, `sendEmail`, `webhook`, `condition`, `aiAnalyze`,
`aiClassifyIntent`, etc.) tells you which node class the error belongs
to, and the step `input` shows the resolved values the node actually
received — compare them against the node's configured fields.

## Retry vs. fix

Some failures are retry-safe and some are not. Decide by class:

* **Retry is useless** when the gate is deterministic — compliance
  opt-outs, a paused/invalid sender pool with no eligible senders, a
  template that never got Meta approval, or a malformed recipient
  field. A retry re-runs the same gate and fails the same way. Fix the
  gate first; the queue-side equivalents (quiet hours, sender-pool
  exhaustion, compliance gates) are the
  [message stuck in queued](/reference/troubleshooting) page.
* **Retry is reasonable** for upstream flakiness — a webhook endpoint
  that 503'd once, an AI analysis endpoint that timed out, a provider
  outage. Fix the upstream and re-run, or accept
  `completed_with_errors` when the error edge handled it.

## When to export the trace for support

Escalate to support when:

* The same flow keeps failing on the same node after the obvious fix
  (you corrected the input, the sender pool, the channel) and it still
  returns the same `error`.
* A run reports `timeout` or `exceeded maximum of ... steps` and the
  flow looks well-formed.
* The `flow_name` row shows `"Untitled flow"` (deleted flow) but
  executions keep arriving.

Export the trace for context: copy the full single-execution JSON from
`GET /api/v1/flows/executions/:id` — the `steps` array, `error`, and
`trigger_data` — and include your tenant id (Settings → Organization)
and the execution id. That pair lets support pull the executor-side
trace without a back-and-forth.

## Error examples: what the strings mean

The strings in `error` are the node's own failure message, verbatim.
A short decode table:

| `error` string                                                                     | Reads as                                                                                                               |
| ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `to must be a valid E.164 phone number`                                            | Send node received a malformed recipient — fix the input mapping.                                                      |
| `Webhook URL targets a private/internal address`                                   | The webhook node's URL resolved to an internal IP — the platform blocks SSRF by design; point it at a public endpoint. |
| `Invalid webhook HTTP method '...' — allowed: GET, POST, PUT, PATCH, DELETE, HEAD` | The node used a method outside the allowed set.                                                                        |
| `Webhook returned 500` (or other 5xx)                                              | The upstream endpoint failed; retries were exhausted.                                                                  |
| `Condition expression exceeds maximum length of 10000 characters`                  | The condition node's expression is oversized — shorten it.                                                             |
| `Unterminated string literal`                                                      | The condition expression has a quoting bug.                                                                            |
| `Forbidden identifier: <name>`                                                     | The expression touches a blocked global (e.g. `process`, `eval`).                                                      |
| `Method '<name>' is not allowed`                                                   | The expression used a string method outside `includes` / `startsWith` / `endsWith`.                                    |
| `Flow <id> is not published (status: ...)`                                         | A run was triggered on a draft/archived flow.                                                                          |
| `exceeded maximum of <N> steps — possible runaway flow`                            | The loop/step guard tripped — check for a cycle in the edges.                                                          |

## See also

* [Flow Executions](/flows/executions) — the API reference for the
  status set and per-step data this page reads.
* [Troubleshooting: message stuck in queued](/reference/troubleshooting)
  — the queue-side gates (quiet hours, sender pools, compliance) that
  also abort sends.
* [Webhook events](/webhooks/events) — subscribe to
  `flow.execution.failed` so failures trigger your own alerting.
