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

# Handling failures

> Tell apart infrastructure faults, agent giving up, and off-schema answers, and decide what to retry.

Sessions do not always end with `completed`. When one ends `failed` or `timed_out`, the session's status carries two machine-readable signals so your code can branch without parsing prose:

* **`error_code`**: why the session failed, from a small fixed taxonomy.
* **`error`**: a short, stable, human-readable message matching the code.

Sessions that finish normally carry a third signal, **`outcome`**: the agent's own assessment of how the task went, reported together with its final answer. A session can be `completed` and still not have done what you asked, so check `outcome` before trusting the answer.

All three appear on [`status`](/computer-use-agents/sessions/status), on the [Session object](/computer-use-agents/sessions/overview), and on [`changes`](/computer-use-agents/sessions/changes).

## Error codes

| `error_code`        | Meaning                                                                                          | Retry?                                                 |
| ------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------ |
| `environment_error` | The session's environment (browser, desktop) failed to provision or crashed.                     | Yes, as is. Nothing about your request was wrong.      |
| `no_answer`         | The agent ran out of budget (`max_steps` / `max_time_s`) or stopped without producing an answer. | Yes, with a higher budget or a more focused task.      |
| `answer_validation` | The agent answered, but every attempt failed to match the agent's `answer_format`.               | Maybe. Simplify the schema, or loosen required fields. |
| `timeout`           | The session exceeded its maximum allowed time (`status` is `timed_out`).                         | Yes, with a higher `max_time_s` or a smaller task.     |
| `internal`          | An unexpected platform-side error.                                                               | Yes, once; if it persists, contact support.            |

`error_code` is `null` unless the session's status is `failed` or `timed_out`, and new codes may be added over time, so treat unknown values like `internal`.

```python Python theme={null}
from hai_agents import Client

client = Client()
result = client.run_session(
    agent="h/web-surfer-flash",
    messages="Find the current price of the Framework 13 laptop",
)

if result.status in ("failed", "timed_out"):
    if result.error_code == "environment_error":
        result = client.run_session(...)  # transient: retry as is
    elif result.error_code in ("no_answer", "timeout"):
        ...  # raise the budget or narrow the task before retrying
    else:
        raise RuntimeError(f"Session failed: {result.error} ({result.error_code})")
```

## Outcomes

With its final answer, the agent reports how the task concluded:

| `outcome`    | Meaning                                                                                |
| ------------ | -------------------------------------------------------------------------------------- |
| `success`    | The task was fully accomplished.                                                       |
| `partial`    | Some of the task was accomplished, but not all of it.                                  |
| `infeasible` | The task cannot be accomplished as specified (e.g. the requested item does not exist). |
| `blocked`    | An external obstacle stopped progress: a login wall, captcha, or missing permissions.  |

The outcome is the agent's self-assessment, not a verified ground truth. It is a strong routing signal (`blocked` usually means a human needs to connect an account or a [vault](/computer-use-agents/vaults/overview); `infeasible` usually means retrying is pointless), but for high-stakes flows validate the answer itself. `outcome` is `null` when the agent ended without reporting one, including all sessions that predate this field.

```typescript TypeScript theme={null}
import { HaiAgentsClient } from "hai-agents";

const client = new HaiAgentsClient();
const result = await client.runSession({
  agent: "h/web-surfer-flash",
  messages: "Cancel my Acme Co subscription",
});

switch (result.outcome) {
  case "success":
    return result.answer;
  case "blocked":
    // needs credentials or a human in the loop
    return escalate(result);
  case "infeasible":
    return giveUp(result);
  default:
    // "partial", null: inspect before trusting
    return review(result);
}
```

## What you will never see

The `error` message is a stable template derived from `error_code`, never raw internals: no tracebacks, file paths, or provider error strings. Do not match on the message text; branch on `error_code` and log the message.

## Related

* [Session lifecycle](/computer-use-agents/sessions/overview#lifecycle) for how sessions reach terminal states.
* [Errors](/computer-use-agents/errors) for HTTP-level error handling (4xx/5xx envelopes, rate limits).
* [Structured output](/computer-use-agents/structured-output) for `answer_format` and SDK-side answer validation.
