---
title: "Troubleshoot the SDK: task outcomes and error fixes"
description: "Maps Duale AI SDK symptoms to causes and fixes for model() outcomes, credential errors, Library calls, and Tool Host failures."
lang: en
status: public-preview
lastUpdated: 2026-10-21
url: https://duale.ai/en/docs/sdk/troubleshooting
---

## AI-generated summary

This guide covers model() error handling, task submission outcomes, credentials and access, libraries and documents, Tool Host errors, and support requests.

- model() error branches and task submission outcomes.
- Credentials and access error resolution.
- Libraries and documents troubleshooting.
- Tool Host startup and runtime errors.
- Support request details and required identifiers.

Summaries were generated by AI.

---

Keep `response.task_id` before anything else: you need it to find what happened to the Task. An `AgentResponse` alone
does not prove that Duale AI accepted the Task. Start from what your application observed, then follow the matching
branch. [SDK errors](https://duale.ai/en/docs/sdk/errors.md) lists every exception, field, and code named here.

## Decide what to do when `model()` raises

```mermaid
flowchart TB
    accTitle: Decide what to do when model raises
    accDescr {
      When awaiting response.model raises, keep the Task identifier first. A
      connection error means the SDK lost sight of the Task, not that the Task
      failed, so check before you submit new work. An authentication or
      permission error needs a credential or access fix. A stopped Task needs
      no retry. A validation error means the result did not match your
      response model. For a failed Task, read its problem details: an owner
      action means a configuration change, a retryable failure can be
      submitted again after your own backoff, and any other failure needs a
      changed request.
    }
    Raised["model() raises"]
    Keep[Keep the task_id]
    Conn{DualeAIConnectionError?}
    Lost[Observation failed. The Task can still finish. Check before new work]
    Auth{DualeAIAuthError?}
    Access[Fix the credential or the permission]
    Stopped{TaskStoppedError?}
    Done[Stopped as requested. No retry]
    Invalid{ValidationError?}
    Schema[Align the response model or the instruction]
    Owner{owner_action_required?}
    Config[Ask the configuration owner to change the model pool]
    Retry{retryable is true?}
    Again[Submit again after your own backoff]
    Change[Change the request first]

    Raised --> Keep
    Keep --> Conn
    Conn -- Yes --> Lost
    Conn -- No --> Auth
    Auth -- Yes --> Access
    Auth -- No --> Stopped
    Stopped -- Yes --> Done
    Stopped -- No --> Invalid
    Invalid -- Yes --> Schema
    Invalid -- No --> Owner
    Owner -- Yes --> Config
    Owner -- No --> Retry
    Retry -- Yes --> Again
    Retry -- No --> Change
```

The SDK's own stream recovery has already run when `model()` raises. Any repeat you decide on is new work, with your
own backoff: a failed Task carries no `retry_after_seconds`. This excerpt follows the same order and uses your
`response` and application handlers:

```python
from dualeai import (
    DualeAIAuthError,
    DualeAIConnectionError,
    DualeAIError,
    TaskStoppedError,
    ValidationError,
)

task_id = response.task_id
try:
    result = await response.model()
except DualeAIConnectionError:
    # Observation failed; the Task can still finish. Check before new work.
    record_unobserved_task(task_id)
except DualeAIAuthError:
    fix_credential_or_permission(task_id)
except TaskStoppedError as stopped:
    record_stopped_task(task_id, stopped.reason)
except ValidationError:
    review_response_model(task_id)
except DualeAIError as exc:
    details = exc.problem_details
    if details is not None and details.owner_action_required:
        notify_configuration_owner(task_id, details)
    elif details is not None and details.retryable:
        schedule_resubmission(task_id)  # Your own backoff.
    else:
        change_the_request(task_id, details)
```

**Check.** Each handled branch records the `task_id` and the outcome before your application submits new work.

## Task submission and outcomes

| Symptom                                                 | Cause                                                                                                 | Fix                                                                                                                                                                                                                                                                                                                                 |
| ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `await response.model()` has not returned when expected | The SDK has not observed a final event; final-answer writing can continue briefly after the deadline. | `model()` has no separate timeout. Keep `response.task_id` and allow for that writing ([deadlines](https://duale.ai/en/docs/agent-harness/executors.md#use-one-deadline-for-each-task)). To end the work, request a Stop; to stop waiting only, cancel your local wait ([Observe the Task outcome](https://duale.ai/en/docs/sdk/concepts.md#observe-the-task-outcome)). |
| `ValidationError` from `model()`                        | The result did not match the response model.                                                          | Align the model with the Task, or drop `res` and read the raw completion.                                                                                                                                                                                                                                                           |
| `DualeAIConnectionError` during a Task stream           | Observation failed after recovery attempts or a non-retryable error.                                  | Read the [stream error context](https://duale.ai/en/docs/sdk/errors.md#task-stream-error-context) and any problem details. Preserve the Task ID; this exception does not prove a failed Task. Check the reported HTTP status or typed cause before repeating work.                                                                                    |
| `error_code` is `CONTENT_FILTERED`                      | No selected model produced an acceptable response; not retryable.                                     | Do not retry unchanged. Inspect `problem_details` and adjust the request.                                                                                                                                                                                                                                                           |
| `TASK_DEADLINE_EXCEEDED` with no Tool Call recorded     | The Agent Identity's Tools grew past the bound on what it can hold.                                   | Remove an assignment; see [Tool limits](https://duale.ai/en/docs/tools/limits.md#how-many-tools-one-agent-identity-can-hold).                                                                                                                                                                                                                         |
| A submission raises `RuntimeError`                      | The SDK's [circuit breaker](https://duale.ai/en/docs/sdk/errors.md#circuit-breaker) is open after repeated failures.    | Wait for the recovery delay, then let one submission check recovery.                                                                                                                                                                                                                                                                |

## Credentials and access

The SDK obtains a platform token before its first protected request and renews it before expiry. Issuance and
mandatory renewal raise `DualeAIAuthError` for `401`/`403`, or `DualeAIConnectionError` for other failures, including
network errors and unusable responses. A failed early renewal can leave a valid token in use. See [Credentials and
lifecycle](https://duale.ai/en/docs/identity/credentials-and-lifecycle.md) before replacing or revoking the API token.

| Symptom                              | Cause                                                                                                                                       | Fix                                                                                                                                                                                                                                                                                                                                                               |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `DualeAIAuthError` with status `401` | The server rejected the token. On a Library call, `DUALEAI_TENANT_ID` can also name a tenant the token was not issued for, or be malformed. | For a Library call, first check that `DUALEAI_TENANT_ID` is the tenant the token was issued for. Otherwise ask someone with `agent:create_token` to issue a replacement [Agent Identity token](https://duale.ai/en/docs/identity/credentials-and-lifecycle.md), then revoke the old token if still active. Set `DUALEAI_TOKEN` to the replacement, including its `dualeai_` prefix. |
| `ACR_STEPUP_REQUIRED`                | The operation needs a higher authentication level than an API token reaches, such as deleting a whole Library.                              | Use the Dashboard.                                                                                                                                                                                                                                                                                                                                                |
| `DualeAIAuthError` with status `403` | The token's caller lacks the action required by that operation.                                                                             | For a Library call, find the checked action in [Library actions](https://duale.ai/en/docs/sdk/reference.md#library-actions), then correct the Grant or policy. For a Task call, find it in [Task actions](https://duale.ai/en/docs/sdk/reference.md#task-actions). For another operation, verify the caller and its documented access before repeating it.                                            |
| Configuration error at startup       | A required setting is missing or malformed.                                                                                                 | Follow [Exceptions outside the hierarchy](https://duale.ai/en/docs/sdk/errors.md#exceptions-outside-the-hierarchy) and check the [environment variables](https://duale.ai/en/docs/sdk/configuration.md#environment-variables).                                                                                                                                                                        |

## Libraries and documents

| Symptom                                                                               | Cause                                                                                   | Fix                                                                                                                                                                                                                                                                                                          |
| ------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `BusinessError` during a Library call                                                 | The Library rejected the operation with a `4xx`.                                        | Read `problem_details.error_code` and follow its row in [Library request codes](https://duale.ai/en/docs/sdk/errors.md#library-request-codes).                                                                                                                                                                                 |
| `DualeAIConnectionError` while connecting, renewing credentials, or calling a Library | Issuance failed outside `401`/`403`, the network failed, or the Library returned `5xx`. | Check `DUALEAI_ENDPOINT` and [network egress](https://duale.ai/en/docs/sdk/configuration.md#allow-outbound-destinations). If problem details exist, retry only when `retryable` is true. Without problem details, retry safe reads. Before repeating a write whose outcome is unknown, follow that operation's recovery steps. |
| `LibraryUploadError`                                                                  | A local file read or an upload part failed.                                             | Read `attachment_key` and `part_number`; preserve `completed_receipts`, then [recover the partial upload](https://duale.ai/en/docs/sdk/manage-libraries.md#recover-a-partial-upload).                                                                                                                                          |
| `wait_for_document()` returns a `failed` document                                     | The document failed processing.                                                         | Follow its row in [Document ingestion failures](https://duale.ai/en/docs/sdk/errors.md#document-ingestion-failures).                                                                                                                                                                                                           |
| `wait_for_document()` raises `TimeoutError`                                           | The client wait ended; processing can still continue.                                   | Poll the same document with `get_document()`; do not upload it again.                                                                                                                                                                                                                                        |
| A `ready` document preview shows only an encryption type or rights label              | A password or a rights label protects the file.                                         | Duale AI made only that protection metadata searchable. Remove the protection, upload the file again, and confirm that the preview now contains the source text.                                                                                                                                             |
| A `ready` scan or figure gives no visual answer                                       | No configured route carried the picture, or a route limit dropped it.                   | Configure an image-capable Model Route whose limits admit the pictures, then repeat a question that only one picture answers. [Images in a document](https://duale.ai/en/docs/sdk/attachments.md#images-in-a-document) covers the setup.                                                                                       |

## Tool Host

| Symptom                                                      | Cause                                                                                                                                                                 | Fix                                                                                                                                                                            |
| ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Serving Tools raises an error about `agent_id`               | No Agent Identity identifier is configured.                                                                                                                           | Set `DUALEAI_AGENT_ID` to a provisioned Agent Identity before `sdk.serve()`.                                                                                                   |
| `sdk.serve()` raises `BusinessError` at startup              | Duale AI rejected the manifest.                                                                                                                                       | Read `problem_details.error_code` and follow its row in [Tool Host errors](https://duale.ai/en/docs/sdk/errors.md#tool-host-errors).                                                             |
| `@tool` raises `ValueError` when the function is declared    | The function uses a reserved Tool name.                                                                                                                               | Rename the function; [Tool Host errors](https://duale.ai/en/docs/sdk/errors.md#tool-host-errors) lists the reserved names.                                                                       |
| `sdk.serve()` stops after failed heartbeats                  | Three consecutive heartbeats failed, for example with `RATE_LIMIT_EXCEEDED` when several processes serve one Agent Identity, or two were refused with `401` or `403`. | Run one Tool Host process per Agent Identity. For a refusal, check the token and its `agent:heartbeat` permission. Then restart `serve()`.                                     |
| A Tool Result submission fails with `REQUEST_BODY_TOO_LARGE` | The result is larger than one submission accepts.                                                                                                                     | Return identifiers, summaries, or rows instead; see [Keep the Tool Result small](https://duale.ai/en/docs/sdk/tools.md#keep-the-tool-result-small).                                              |
| Built-in `TimeoutError` from an `@activity`                  | The wait for scheduled activity work exceeded `job_timeout`.                                                                                                          | Treat the Effect as uncertain. Cancellation cannot roll back an external action that already completed. [Activity caching](https://duale.ai/en/docs/sdk/activity-caching.md) explains the timer. |

## Ask for support

If a failure persists, email [technical support](mailto:contact+support@mail.duale.ai) with the `task_id`, the
`error_code`, the `trace_id` and `span_id` when present, the `request_id` for an HTTP rejection, and the stream
context's `operation`, `retry_attempt`, and HTTP status. Never send the API token or a platform token.

## Related content

- [SDK exceptions, error codes, and task outcomes](https://duale.ai/en/docs/sdk/errors.md)
- [Documentation: integration, capabilities, and limits](https://duale.ai/en/docs.md)
- [Task lifecycle: submission, outcomes, and continuations](https://duale.ai/en/docs/sdk/concepts.md)
- [Manage Libraries: create, upload, and verify ingestion](https://duale.ai/en/docs/sdk/manage-libraries.md)
- [Product: Task execution and platform capabilities](https://duale.ai/en/product.md)
- [Python SDK reference: ask, next, AgentResponse](https://duale.ai/en/docs/sdk/reference.md)

---

## Sitemap

See the full [Markdown sitemap](https://duale.ai/sitemap.md) for all pages.
