The Two Error Types
The SDK throws two kinds of error. Both give you a readablelocalizedDescription.
Swift errors are not arranged in a hierarchy, so there is no single type that catches both. Match each one, and keep a final
catch for anything else, such as a CancellationError or an error from your own tool handler.
APIError
case
The server sent something that was not an HTTP response. Rare. Treat it like a network problem.
case
The server returned an error status.
detail holds the code you can check in your app.case
The request never got through: no connection, DNS failure, or a timeout. The value inside is the underlying
URLError.Shortcuts
APIErrorDetail
String
required
The error code. Check this in your app, never the
message.String
required
A description written for developers.
[String: String]?
Which fields were wrong, when the server tells you.
.httpError with code set to "UNKNOWN", so you never lose the status code.
ChatError
Error Codes
These are the codes you can get fromAPIError.apiCode:
| Status | Code | Description |
|---|---|---|
| 400 | VALIDATION_INVALID_BODY | The request was not valid. details says which fields were wrong. You also get this when a tool result is over 20 KB. |
| 400 | VALIDATION_INVALID_JSON | The request body was not valid JSON. |
| 400 | VALIDATION_MISSING_USER_IDENTIFIER | The device ID header was missing. You should not see this, since the SDK always sends it. |
| 400 | AUTH_INVALID_USER_AGENT | The SDK’s User-Agent header was missing or not recognized. You should only see this if something rewrites your headers. |
| 400 | CHAT_RETRY_NO_USER_MESSAGE | The message you passed to retry() has no user message before it to answer. |
| 401 | AUTH_INVALID_JWT | The token you passed to identify(), or the saved token on a later request, is invalid or expired. You also get this when identity verification is not set up for the agent. See User Identity. |
| 402 | CHAT_CREDITS_EXHAUSTED | The workspace has no message credits left. Upgrade the plan or wait for credits to reset. |
| 402 | CHAT_AGENT_CREDITS_EXHAUSTED | This agent has used up its share of credits. |
| 403 | AUTH_OWNERSHIP_MISMATCH | The conversation belongs to a different user or device. retry() and listMessages() also return this when the conversation does not exist. |
| 403 | CHAT_CONVERSATION_MISMATCH | The conversation does not belong to this agent. |
| 403 | CHAT_MODEL_NOT_ALLOWED | The agent uses a model that the current plan does not include. |
| 403 | CHAT_CONVERSATION_NOT_ONGOING | The conversation has ended, or a person took it over, so it cannot take new messages. Start a new one. |
| 404 | AGENT_NOT_FOUND | No agent has that ID, or the iOS SDK channel is turned off for the agent. See Quick Start. |
| 404 | RESOURCE_NOT_FOUND | The conversation or message does not exist. |
| 404 | CHAT_RETRY_MESSAGE_NOT_FOUND | The message ID you gave retry() was not found. |
| 404 | RESOURCE_TOOL_CALL_NOT_FOUND | The tool call was not found, or it expired. This can come up during the tool loop. |
| 404 | RESOURCE_TOOL_CALL_MISMATCH | The tool call belongs to a different conversation. |
| 404 | RESOURCE_TOOL_RESULT_NOT_PENDING | The server was not waiting for this tool result. Usually it was sent twice. |
| 429 | RATE_LIMIT_TOO_MANY_REQUESTS | Too many requests (the limit is 1,000 every 10 seconds per device). Wait and try again. The response includes a Retry-After header. |
| 500 | CHAT_STREAMING_ERROR | The reply failed on the server. Safe to try again. |
| 500 | INTERNAL_SERVER_ERROR | Something went wrong on the server. Try again, or contact support if it keeps happening. |
AGENT_NOT_FOUND looks the same whether the agent does not exist or the iOS SDK channel is turned off. If you are sure the agent ID is right, check Deploy → iOS SDK first.Handling Errors
- async/await
- Network problems
- SwiftUI state
- Rate limits
Errors Inside Tool Handlers
An error thrown by a tool handler does not come out ofsend. The SDK turns it into {"error": "..."} and gives it to the agent, so the agent can recover. See When a Tool Fails.
CancellationError is the exception. It is passed through, so cancelling the Task cancels the reply.
What to Report
The SDK already logs each request and response undercom.chatbase.sdk. See Logging. When you report a problem, include the apiCode, the statusCode, and the time. That is enough to find the request on the server.
Related
Streaming
Where most errors show up
User Identity
Handling expired and rejected tokens
Client-Side Tools
Reporting failures back to the agent
Overview
Setup and configuration
