> ## 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: in-call AI handoff, deflection, and follow-up failures

> Resolve the HANDOFF_FAILED, DEFLECTION_FAILED, and FOLLOWUP_SEND_FAILED codes on the three in-call AI exit lanes — warm handoff to a human queue, deflect-to-digital (SMS/WhatsApp), and post-call follow-up.

# Troubleshooting: in-call AI handoff, deflection, and follow-up failures

A live AI voice agent ends a call one of three ways from inside the call:
it hands the caller to a human queue, it deflects the caller to SMS or
WhatsApp, or it promises a follow-up message after the call ends. Each lane
fails independently of the others, and each surfaces its own 500 code —
`HANDOFF_FAILED`, `DEFLECTION_FAILED`, or `FOLLOWUP_SEND_FAILED`. Read the
code and you know which lane to work; the overall posture is the same for
all three: the failure happened inside the platform's orchestration step,
so retry is limited and the fix is usually one configuration lookup, not a
payload change.

These codes come back from machine-to-machine endpoints the voice gateway
calls when the AI agent invokes a tool (`transfer_to_human`,
`deflect_to_digital`, or the post-call follow-up intent). The gateway is
fire-and-forget, so a 500 here never retries itself — the record of the
failure is the structured error body and the Sentry side the platform
keeps. Your customer's live call is never dropped by any of the three:
`HANDOFF_FAILED` leaves the caller with the AI agent, and the two
message-send failures only lose the digital follow-up, not the call.

## Code matrix — symptom to fix

| Error code             | HTTP | Lane                     | What failed                                                                                                                               | First move                                                                                                                                                      |
| ---------------------- | ---- | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `HANDOFF_FAILED`       | 500  | AI → human queue         | The warm-handoff orchestration — persist the summary packet, bridge the caller into the ACD queue, drop the bot leg — failed mid-sequence | Confirm the queue exists and has capacity, then have the agent retry the tool call — see [Warm handoff returns 500](#warm-handoff-returns-500-handoff_failed)   |
| `DEFLECTION_FAILED`    | 500  | AI → SMS / WhatsApp      | The deflection send failed: an invalid channel enum, or the message dispatch itself rejected                                              | Check the channel is `sms` or `whatsapp` and the sender is resolvable — see [Deflect-to-digital returns 500](#deflect-to-digital-returns-500-deflection_failed) |
| `FOLLOWUP_SEND_FAILED` | 500  | AI → post-call follow-up | The follow-up message send failed on the channel resolved from the agent's promise, the contact's preference, or the SMS fallback         | Re-trigger from the conversation the call opened — see [Post-call follow-up returns 500](#post-call-follow-up-returns-500-followup_send_failed)                 |

Two non-500 responses sit next to these codes and are resolved on your
side, not by a retry:

| Response               | Lane                   | What it means                                                                                                                                                            | Fix                                                                                          |
| ---------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------- |
| `422 VALIDATION_ERROR` | All three              | A required field is missing or malformed (the queue id, the channel enum, an empty body field)                                                                           | Read `error.details` for the field; correct the agent tool definition or the flow that posts |
| `204 No Content`       | Deflection / follow-up | Intentional skip — an empty message body, or no destination address exists for the channel the agent promised (e.g. email promised but the contact has no email on file) | Only retry if the missing configuration is restored; otherwise accept the skip               |

## Warm handoff returns 500 — HANDOFF\_FAILED

`POST /api/v1/internal/voice/ai-handoff` is invoked by the gateway when the
live AI agent session calls the `transfer_to_human` tool. The
orchestration persists a context packet (call summary, sentiment, key
topics, action items, collected slots) onto the call record, bridges the
caller into the named ACD queue, and — when a conference id is supplied —
drops the bot leg once the caller is safely queued. A 500 means that
sequence broke somewhere between the packet write and the queue bridge;
the caller is still talking to the AI agent, and no handoff packet is
guaranteed.

Work it in this order:

1. **Confirm the queue exists and accepts entries.** The most common
   cause is a queue id the agent names that does not resolve — deleted
   since the agent prompt was authored, or a typo in the tool definition.
   Open the queue in the dashboard (Voice → Queues) and retry the tool
   call. A queue at capacity rejects the same way; see
   [Queue capacity gates](/troubleshooting/queue-capacity-gates).
2. **Check required-skills plausibility.** When the agent supplies
   `required_skills`, the queue has to hold an agent with those skills to
   answer; mismatched skills suspend the handoff. Either align the skills
   or drop them from the tool definition.
3. **Look at the agent-runtime logs.** The log line is
   `voice-ai-handoff: orchestration failed` and it carries the underlying
   error message plus the call, session, and queue ids — the first thing a
   report needs. The dashboard status page does not expose these; pull
   them from your log drain or ask support for the request id.
4. **Retry once with the same call id.** The packet write and the queue
   enqueue are idempotent on the call, so a single retry after the queue
   check is safe. Persistent 500s after that are platform-side — escalate.
5. **Distinguish from supervisor takeovers.** `SUPERVISOR_*` codes on
   [supervisor takeover failures](/troubleshooting/supervisor-takeover-failures)
   cover a human supervisor coaching surface; `HANDOFF_FAILED` is the AI
   bot exiting itself. The two lanes share the queue but not the codes.

Agent-side behavior to expect: the voice agent keeps the caller engaged
while a handoff is pending, so a failed handoff is invisible to the caller
until your retry succeeds. The failure shows on the dashboard's agent
session detail for that call as a failed `transfer_to_human` tool result.

## Deflect-to-digital returns 500 — DEFLECTION\_FAILED

`POST /api/v1/internal/voice/deflect-to-digital` is invoked when the agent
calls `deflect_to_digital` — "I'll text you a link to finish this". It
opens (or attaches to) a linked conversation on the target channel, stamps
the call context onto it, and sends the agent's opening message through
the same messaging envelope any other outbound message uses. A 500 means
the send step rejected; the call continues.

Work it in this order:

1. **Only `sms` and `whatsapp` are valid channels.** A prompt that lets
   the agent promise email or voice as the deflection target breaks here —
   restrict the tool definition to the two enums. That is a request-side
   fix; retrying a 422-class reject never converges.
2. **Resolve the sender.** The message sends from the same number the
   call landed on (`agent_phone`, when the gateway knows it) or the org's
   default sender when it is `null`. A tenant with no default sender and a
   null agent phone fails the send — set a default sender in
   Settings → Channels, or ensure the DID the inbound call hits is sender-
   capable. See [Sender resolution errors](/troubleshooting/sender-resolution-errors).
3. **Content gates also count.** The same messaging envelope applies the
   file-scan and compliance gates any outbound message applies — a link to
   a quarantined attachment blocks the same way it would from the inbox
   composer. The rejection reaches this endpoint as a 500, so check the
   message body against [file-scan quarantine](/troubleshooting/file-scan-quarantined)
   before treating it as platform-side.
4. **Idempotency is on (call, channel).** A retry of the same deflection
   for the same call and channel returns `200 already_deflected` rather
   than double-sending — so retry is safe, and a duplicate `201` is the
   bug to report, not the retry.

On the dashboard, the call's agent session shows the deflection tool
result as failed; the conversation it would have opened does not appear in
the inbox. If the send *had* succeeded, the opening message id and the
conversation id come back on the 201 response — capture them when you
report a partial flow.

## Post-call follow-up returns 500 — FOLLOWUP\_SEND\_FAILED

`POST /api/v1/internal/conversations/post-call-followup` is invoked during
voice-gateway teardown when the agent verbally promised a follow-up
("I'll text you", "we'll email you"). It picks a channel from the agent's
promise first, the contact's preferred channel second, and SMS as the
always-available fallback, then renders the follow-up body from the call
summary and sends it through the messaging envelope. A 500 means the send
rejected after a channel was resolved; if no channel resolved at all the
endpoint returns 204 by design, not this code.

Work it in this order:

1. **Read the resolved channel.** The endpoint logs the channel it picked
   (`sms`, `email`, or `whatsapp`) before it fails, and the 500's lane is
   that channel. Work the channel-specific gate: for SMS/WhatsApp the
   sender-resolution and destination checks above; for email the
   [email bounces and complaints](/troubleshooting/email-bounces-complaints)
   surface.
2. **The contact record matters.** An email follow-up needs the contact's
   email; when it is absent the endpoint returns 204, not a 500. A 500 on
   email means the address existed and the dispatch failed — check email
   DNS posture on [email DNS drift](/troubleshooting/email-dns-drift).
3. **Re-trigger by resending the follow-up summary.** There is no
   customer-callable retry endpoint for this lane — the gateway already
   tore the session down. The safe re-trigger is to send the follow-up
   manually from the conversation the call opened (Inbox → pick the
   caller's thread → send), or re-queue it via the messages API with the
   same summary text. The `metadata.source = voice_post_call_followup`
   tag on the original attempt marks it on the call's interaction record.
4. **Idempotency is on (call).** Retry of the same call id lands as
   `200 already_enqueued`, so an accidental re-POST never double-sends —
   only the manual re-send steps above will.

On the dashboard, the session ended cleanly (this failure is post-call);
the only artifact is the missing follow-up message on the caller's thread
and the failed tool result on the session detail.

## What NOT to try

* **Do not loop the retry.** All three lanes are orchestration calls with
  bounded retry-safety (a single re-issue after configuration checks). The
  gateway's fire-and-forget posture means a webhook-driven immediate
  re-POST turns one failure into a retry storm.
* **Do not treat 204 as failure.** An empty message body or a missing
  destination address (email promised, none on file) short-circuits with
  `204 No Content` and a metric bump — that is by design. Retry only after
  the missing configuration is restored.
* **Do not confuse lanes.** Supervisor-coaching failures are
  `SUPERVISOR_*` and live on [their own page](/troubleshooting/supervisor-takeover-failures).
  Media-path complaints after a successful handoff live on
  [voice call quality](/troubleshooting/voice-call-quality). Neither lane
  belongs here.
* **Do not fix the caller's experience in-place.** A failed handoff keeps
  the caller with the AI; a failed deflection or follow-up loses only the
  digital message. None of the three drop the call — do not escalate
  these as call-quality incidents.

## What to capture before escalating

Work the matching lane first. If the same code persists after the checks
it names, open a ticket with:

1. **The error code and HTTP status**, verbatim (`HANDOFF_FAILED`,
   `DEFLECTION_FAILED`, or `FOLLOWUP_SEND_FAILED`, 500).
2. **The request ID** from `meta.request_id` on the failing response —
   the platform Sentry record is keyed to it.
3. **The call ID and session ID** off the request — either on the tool
   call the agent logged or from the call detail view.
4. **The lane-specific detail**: the queue id the agent named for
   handoff; the channel and sender for deflection; the resolved channel
   and the contact's address presence for follow-up.
5. **Your organization ID** (Settings → Organization, or
   `organizationId` from `GET /api/v1/me`).

## See also

* [Guide: hand off an AI voice call to a human](/guides/voice-ai-handoff-to-human) —
  the happy-path walkthrough for the same lane `HANDOFF_FAILED` breaks on.
* [Supervisor takeover, whisper, and barge failures](/troubleshooting/supervisor-takeover-failures) —
  the human-coaching lane that is deliberately not this page.
* [Sender resolution errors](/troubleshooting/sender-resolution-errors) —
  the deflection and follow-up lanes both inherit sender checks.
* [Queue capacity gates](/troubleshooting/queue-capacity-gates) — a full
  queue rejects a handoff the same way a missing one does.
* [Error codes reference](/reference/error-codes) — the platform-wide
  catalog this page maps three codes into.
