Skip to main content

The Two Error Types

The SDK throws two kinds of error. Both give you a readable localizedDescription. 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.
message is written for developers. It is not translated and not meant for your users. Turn code into your own wording instead of showing localizedDescription on screen.
If the error body cannot be read, the SDK still throws .httpError with code set to "UNKNOWN", so you never lose the status code.

ChatError

Error Codes

These are the codes you can get from APIError.apiCode:
StatusCodeDescription
400VALIDATION_INVALID_BODYThe request was not valid. details says which fields were wrong. You also get this when a tool result is over 20 KB.
400VALIDATION_INVALID_JSONThe request body was not valid JSON.
400VALIDATION_MISSING_USER_IDENTIFIERThe device ID header was missing. You should not see this, since the SDK always sends it.
400AUTH_INVALID_USER_AGENTThe SDK’s User-Agent header was missing or not recognized. You should only see this if something rewrites your headers.
400CHAT_RETRY_NO_USER_MESSAGEThe message you passed to retry() has no user message before it to answer.
401AUTH_INVALID_JWTThe 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.
402CHAT_CREDITS_EXHAUSTEDThe workspace has no message credits left. Upgrade the plan or wait for credits to reset.
402CHAT_AGENT_CREDITS_EXHAUSTEDThis agent has used up its share of credits.
403AUTH_OWNERSHIP_MISMATCHThe conversation belongs to a different user or device. retry() and listMessages() also return this when the conversation does not exist.
403CHAT_CONVERSATION_MISMATCHThe conversation does not belong to this agent.
403CHAT_MODEL_NOT_ALLOWEDThe agent uses a model that the current plan does not include.
403CHAT_CONVERSATION_NOT_ONGOINGThe conversation has ended, or a person took it over, so it cannot take new messages. Start a new one.
404AGENT_NOT_FOUNDNo agent has that ID, or the iOS SDK channel is turned off for the agent. See Quick Start.
404RESOURCE_NOT_FOUNDThe conversation or message does not exist.
404CHAT_RETRY_MESSAGE_NOT_FOUNDThe message ID you gave retry() was not found.
404RESOURCE_TOOL_CALL_NOT_FOUNDThe tool call was not found, or it expired. This can come up during the tool loop.
404RESOURCE_TOOL_CALL_MISMATCHThe tool call belongs to a different conversation.
404RESOURCE_TOOL_RESULT_NOT_PENDINGThe server was not waiting for this tool result. Usually it was sent twice.
429RATE_LIMIT_TOO_MANY_REQUESTSToo many requests (the limit is 1,000 every 10 seconds per device). Wait and try again. The response includes a Retry-After header.
500CHAT_STREAMING_ERRORThe reply failed on the server. Safe to try again.
500INTERNAL_SERVER_ERRORSomething 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 DeployiOS SDK first.

Handling Errors

Errors Inside Tool Handlers

An error thrown by a tool handler does not come out of send. 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 under com.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.
Do not send tokens or message text to a crash reporting service. APIError.localizedDescription is safe. It contains only the code, the message, and the status.

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