- Duale AI
- Documentation
- Python SDK
- SDK troubleshooting
SDK troubleshooting: symptoms, causes, and fixes
Match Duale AI SDK error symptoms to causes and fixes for model() exceptions, authentication, libraries, documents, and Tool Host issues.
This page covers troubleshooting for SDK errors across task outcomes, credentials, libraries, documents, and Tool Host operations.
- Task submission outcomes and model() error handling.
- Credentials and access error resolution.
- Library and document processing failures.
- Tool Host startup, heartbeat, and result errors.
- Support request details to include.
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 lists every exception, field, and code named here.
Decide what to do when model() raises
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:
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). To end the work, request a Stop; to stop waiting only, cancel your local wait (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 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. |
error_code is REQUEST_BLOCKED | A safety check blocked the request that started or continued the Task: it judged that the request tries to make the model ignore its instructions, reveal its instructions or credentials, or speak for the platform, or it failed to judge the request, for example because your model provider refused to read it; not retryable. | Find where the request text came from and remove or rephrase that part. If the request is benign, check whether your model provider filters its subject. Then continue the Task with the complete changed request: later model calls read a notice instead of the blocked one (Task outcomes). |
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. |
A submission raises RuntimeError | The SDK’s circuit breaker is open after repeated failures. | Wait for the recovery delay, then let one submission check recovery. |
- Symptom
await response.model()has not returned when expected- Cause
- The SDK has not observed a final event; final-answer writing can continue briefly after the deadline.
- Fix
model()has no separate timeout. Keepresponse.task_idand allow for that writing (deadlines). To end the work, request a Stop; to stop waiting only, cancel your local wait (Observe the Task outcome).
- Symptom
ValidationErrorfrommodel()- Cause
- The result did not match the response model.
- Fix
- Align the model with the Task, or drop
resand read the raw completion.
- Symptom
DualeAIConnectionErrorduring a Task stream- Cause
- Observation failed after recovery attempts or a non-retryable error.
- Fix
- Read the 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.
- Symptom
error_codeisCONTENT_FILTERED- Cause
- No selected model produced an acceptable response; not retryable.
- Fix
- Do not retry unchanged. Inspect
problem_detailsand adjust the request.
- Symptom
error_codeisREQUEST_BLOCKED- Cause
- A safety check blocked the request that started or continued the Task: it judged that the request tries to make the model ignore its instructions, reveal its instructions or credentials, or speak for the platform, or it failed to judge the request, for example because your model provider refused to read it; not retryable.
- Fix
- Find where the request text came from and remove or rephrase that part. If the request is benign, check whether your model provider filters its subject. Then continue the Task with the complete changed request: later model calls read a notice instead of the blocked one (Task outcomes).
- Symptom
TASK_DEADLINE_EXCEEDEDwith no Tool Call recorded- Cause
- The Agent Identity’s Tools grew past the bound on what it can hold.
- Fix
- Remove an assignment; see Tool limits.
- Symptom
- A submission raises
RuntimeError - Cause
- The SDK’s circuit breaker is open after repeated failures.
- Fix
- 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 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, 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, then correct the Grant or policy. For a Task call, find it in 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 and check the environment variables. |
- Symptom
DualeAIAuthErrorwith status401- Cause
- The server rejected the token. On a Library call,
DUALEAI_TENANT_IDcan also name a tenant the token was not issued for, or be malformed. - Fix
- For a Library call, first check that
DUALEAI_TENANT_IDis the tenant the token was issued for. Otherwise ask someone withagent:create_tokento issue a replacement Agent Identity token, then revoke the old token if still active. SetDUALEAI_TOKENto the replacement, including itsdualeai_prefix.
- Symptom
ACR_STEPUP_REQUIRED- Cause
- The operation needs a higher authentication level than an API token reaches, such as deleting a whole Library.
- Fix
- Use the Dashboard.
- Symptom
DualeAIAuthErrorwith status403- Cause
- The token’s caller lacks the action required by that operation.
- Fix
- For a Library call, find the checked action in Library actions, then correct the Grant or policy. For a Task call, find it in Task actions. For another operation, verify the caller and its documented access before repeating it.
- Symptom
- Configuration error at startup
- Cause
- A required setting is missing or malformed.
- Fix
- Follow Exceptions outside the hierarchy and check the 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. |
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. 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. |
wait_for_document() returns a failed document | The document failed processing. | Follow its row in 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, in a new Task, a question that only one picture answers. Images in a document covers the setup. |
- Symptom
BusinessErrorduring a Library call- Cause
- The Library rejected the operation with a
4xx. - Fix
- Read
problem_details.error_codeand follow its row in Library request codes.
- Symptom
DualeAIConnectionErrorwhile connecting, renewing credentials, or calling a Library- Cause
- Issuance failed outside
401/403, the network failed, or the Library returned5xx. - Fix
- Check
DUALEAI_ENDPOINTand network egress. If problem details exist, retry only whenretryableis true. Without problem details, retry safe reads. Before repeating a write whose outcome is unknown, follow that operation’s recovery steps.
- Symptom
LibraryUploadError- Cause
- A local file read or an upload part failed.
- Fix
- Read
attachment_keyandpart_number; preservecompleted_receipts, then recover the partial upload.
- Symptom
wait_for_document()returns afaileddocument- Cause
- The document failed processing.
- Fix
- Follow its row in Document ingestion failures.
- Symptom
wait_for_document()raisesTimeoutError- Cause
- The client wait ended; processing can still continue.
- Fix
- Poll the same document with
get_document(); do not upload it again.
- Symptom
- A
readydocument preview shows only an encryption type or rights label - Cause
- A password or a rights label protects the file.
- Fix
- 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.
- Symptom
- A
readyscan or figure gives no visual answer - Cause
- No configured route carried the picture, or a route limit dropped it.
- Fix
- Configure an image-capable Model Route whose limits admit the pictures, then repeat, in a new Task, a question that only one picture answers. 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. |
| One Tool shows Schema unsupported and is never offered | A parameter of that Tool has an alias that starts with __, which Duale AI reserves. sdk.serve() raises no error for it. | Give the parameter an alias that does not start with __, then restart the Tool Host. Reserved argument names states the rule. |
@tool raises ValueError when the function is declared | The function uses a reserved Tool name. | Rename the function; 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. |
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 explains the timer. |
| The answer says that a safety check blocked a step, and your function returned a result | A safety check judged that the Tool Result tries to instruct the model, for example to drop its Task or reveal its instructions, or it failed to judge the result. The Tool ran; later model calls read a notice instead of its result, and the Task continued without it. | Return data, not instructions to the model. If the result is benign, check whether your model provider filters its subject. When the Tool passes on content you do not control, such as emails or web pages, this outcome protects the Task. |
| The answer says that a safety check blocked a step, and your function never received the call | A safety check judged that the Tool Call has an effect the Task’s request does not explain, such as sending data to a recipient the request does not name, or it failed to judge the call. Duale AI did not send the call, and the model read that it was blocked. | Name in the request the recipients, destinations, and changes the work needs, then continue the Task. |
Ask for support
If a failure persists, email technical support 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.