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

# Error Handling

> Handle every terminal outcome and error layer deliberately.

Robust phone-agent integrations are not the ones that never fail - they are the ones that classify every failure correctly and know the recovery move. There are three error layers and nine terminal outcomes; this page gives the move for each.

## Know which layer you're in

| Layer        | You'll see                                                                   | It means                                                                                                                                      |
| ------------ | ---------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| **HTTP**     | `401`/`403` with a JSON body and `WWW-Authenticate` header                   | Authentication failed before MCP was reached. Fix credentials - see [Authentication troubleshooting](/guides/troubleshooting/authentication). |
| **JSON-RPC** | An `error` envelope with `error.data.reason`                                 | The tool call was rejected: `device_paused`, `session_not_found_or_inactive`, `task_not_found`. Fix the call, not the task.                   |
| **Task**     | A completed task whose payload has `terminal` and possibly an `error` object | The task ran and ended. Read `terminal` and act.                                                                                              |

The task-level `error` object (holding `error.control_type` and `error.prompt`) is part of the task status payload - distinct from the JSON-RPC envelope.

## A move for every terminal

| Terminal              | Recovery move                                                                                                                                                                                                                  |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `ok`                  | Read `result`. Done.                                                                                                                                                                                                           |
| `needs_user_control`  | Not an error - a handoff. Get the user's answer, send [`phone_task_message`](/api-reference/tools/phone-task-message), monitor the `continuation_task_id`.                                                                     |
| `timeout`             | Retry with a higher `per_call_timeout_s` (max 900) **or** narrow the prompt. If a task keeps timing out, it is oversized - split it.                                                                                           |
| `queue_wait_exceeded` | The phone never started it. Check [`phone_device_status`](/api-reference/tools/phone-device-status) - online? paused? busy with an in-app task? Then start a new task, raising `queue_wait_timeout_s` if contention is normal. |
| `stopped_by_user`     | Expected after cancels, session ends, and displacement by a newer task. Start a new task only if the work is still wanted.                                                                                                     |
| `agent_error`         | Retry once; inspect `error` for details. Repeated `agent_error` on the same prompt usually means the prompt needs disambiguation.                                                                                              |
| `device_offline`      | Reconnect the device (**Settings > Developer connection > Refresh** in the AGI app), verify with `phone_device_status`, retry.                                                                                                 |
| `session_expired`     | Normal for long workflows. Start a new session and continue.                                                                                                                                                                   |
| `iteration_limit`     | The task was too big for the agent's action budget. Split it into smaller tasks in one session.                                                                                                                                |

## Retry discipline

* **Retry the task, not blindly.** `timeout`, `agent_error`, and
  `device_offline` are worth one retry after addressing the cause. Retrying
  `iteration_limit` without splitting, or `queue_wait_exceeded` without
  checking the device, just repeats the failure.
* **Never construct task IDs.** Use exactly what
  [`phone_run_task`](/api-reference/tools/phone-run-task) returned; after a
  handoff, monitor the `continuation_task_id`, not the original. `task_not_found`
  usually means an expired or wrong-session ID - start a replacement task.
* **Cancellation races are benign.** A cancel that arrives after completion
  returns `already_completed: true`; act on the task's real `terminal`.
* **Repeating the same answer** to a `needs_user_control` task is safe;
  sending a *different* second answer is rejected.

## Design failure into the workflow

* Split workflows into per-errand tasks so a failure only costs one step -
  see [Task design](/guides/best-practices/task-design).
* Ask prompts to report "not found" explicitly, so an empty `result` is never
  ambiguous.
* Treat `monitor_timed_out: true` as *keep waiting*, never as failure.

## Related

<CardGroup cols={2}>
  <Card title="Task lifecycle" icon="arrows-spin" href="/guides/concepts/task-lifecycle">
    Where each terminal comes from
  </Card>

  <Card title="Troubleshooting" icon="wrench" href="/guides/troubleshooting">
    Symptom-based debugging
  </Card>
</CardGroup>
