Errors and limits
When a tool call fails, Cademí MCP returns an error with a stable code, a message, and the API request_id when there is one. This page lists the codes, what to do for each, and the limits on response size, time, and load.
Error format
A failed call is a tool result with isError: true. Its text starts with the code and the message, and structuredContent carries the error as an object:
{
"error": {
"code": "RATE_LIMITED",
"message": "Too many requests.",
"retryable": true,
"api_code": "rate_limit_exceeded",
"request_id": "01J8Z3ZQ4H8K2M0T1S9P7YQF5C",
"retry_after_seconds": 12,
"details": { "blocked_by": ["key"] }
}
}| Field | Description |
|---|---|
code | One of the codes below. |
message | What happened, in English. |
retryable | true when the same call may succeed later. |
api_code | The code of the API error, when the API returned one. See Errors. |
request_id | The identifier of the API call, when there is one. |
retry_after_seconds | How long to wait before retrying, when known. |
details | More information, depending on the error: the invalid fields (fields), the candidates of an ambiguous reference (candidates), the missing permissions (missing_permissions), or the API's reason and blocked_by. |
Codes
| Code | Retryable | Meaning | What to do |
|---|---|---|---|
AUTHENTICATION_REQUIRED | No | The authorization of the connection is missing, expired, or revoked, or the API rejected it. | Connect the client again and authorize it (Connect a client). |
PERMISSION_DENIED | No | The administrator does not have the permission, or the API refused the operation for this account, for example because the operation runs only in a sandbox account or the record is a read-only replica. api_code says which. | Use a connection authorized by an administrator with the permission, or grant it. See Authorization and permissions. |
INVALID_ARGUMENT | No | The input was rejected. For validation errors, details.fields lists the invalid fields. | Correct the input. Retrying the same call fails again. |
RESOURCE_NOT_FOUND | No | The resource does not exist or is not accessible. For a composite tool, no student or product matches the reference. | Check the ID or the name, or search with users_list or products_list. |
AMBIGUOUS_REFERENCE | No | A composite tool found several students or products for the reference. details.candidates lists up to 10. | Choose a candidate and call the tool again with its ID (How students and products are found). |
CONFLICT | No | The call conflicts with the current state: the resource changed since the revision you sent in if_match, the transition is not allowed, the resource already exists, or an idempotency key was reused with a different request. | Read the current state and decide again. |
RATE_LIMITED | Yes | The account reached an API limit. | Wait retry_after_seconds when present, then retry. See Limits, quotas, and retention. |
CLI_TIMEOUT | Yes | An API call made by the tool did not finish within the time limit. | Retry. For a call that changes data, check first whether the change was applied, or retry with the same idempotency_key. |
CLI_FAILED | No | The call could not be completed for a reason that no other code covers, or it was cancelled. | Retry once. If it fails again, report it with the request_id. |
CAPACITY_EXHAUSTED | Yes | The server is at capacity. | Retry after retry_after_seconds. |
OUTPUT_TOO_LARGE | No | The API result is too large to return. | Narrow the query with filters or a smaller limit, and page with cursor. |
API_UNAVAILABLE | Yes | The API or the Cademí authorization server is temporarily unavailable, or the API failed with a server error. | Retry later. If api_code is result_uncertain, see Uncertain results. |
INTERNAL_ERROR | No | An unexpected error in the MCP server. | Try again later. If it persists, report it. |
The error codes of the API behind api_code are listed in Errors.
Uncertain results
When a call that changes data fails with api_code set to result_uncertain, the change may have been applied. The error then has retryable: false. A retry is safe only with the same idempotency_key as the first call: if the first attempt was recorded, the API returns its result and applies nothing new. When you omit idempotency_key, a new key is generated for each call, so set it yourself on a call you may need to retry. Without the first key, check whether the change was applied before you call again. The same applies to a CLI_TIMEOUT on a call that changes data. How idempotency works in the API is described in Errors.
Request IDs
When an error comes from the API, it keeps the API's request_id. It is the same identifier as the X-Request-Id header and the audit entry of the call. Composite tools also include the request_id in each entry of warnings for a part that could not be read.
Include the request_id when you report a problem (Report a problem).
Response size
A tool result has a size limit. When a result goes over it:
- Very long text values are shortened, and each one ends with a note that says how many characters were omitted.
- If the result is still too large, items are removed from the end of its largest list until it fits.
A shortened result says so with truncated: true and a truncation object:
{
"truncated": true,
"truncation": {
"hint": "Some items were omitted to fit the response size limit. Call again with a smaller `limit` and follow `page.next_cursor` to see every item.",
"arrays": [{ "path": "items", "returned": 38, "omitted": 12 }]
}
}| Field | Description |
|---|---|
hint | How to get the rest. |
strings_clipped | How many text values were shortened. |
arrays | For each list that lost items, its path in the result, how many items were returned, and how many were omitted. |
When the API result is far above the limit, the tool returns OUTPUT_TOO_LARGE instead. In both cases, ask for less: a smaller limit, filters, or the next page.
Composite tools also read a bounded amount of data. A list they could not read in full has complete: false, and product_structure expands a bounded number of modules (product_structure).
Time and load
- Time limit. Each API call a tool makes has a time limit. A call that goes over it fails with
CLI_TIMEOUT. Composite tools make several API calls, some of them in parallel. - Cancellation. If your client cancels a tool call, the server stops it, with the code
CLI_FAILED. A change that the call already sent to the API may still be applied. - Server capacity. When the server is busy, a call waits briefly for a slot. If none frees up, it fails with
CAPACITY_EXHAUSTEDandretry_after_seconds. - API limits. Tool calls count toward the API limits of your account, like calls from any other client. See Limits, quotas, and retention.