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. When the items of the API error carry a reason, the text adds the api_code and those reasons in parentheses, at most five, followed by …+N when there are more, for example (feature_disabled, reason: first_import_requires_release). The text ends with the request_id when there is one. 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: every item of the API error's details[] (fields), including the invalid fields and each reason, 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 the students or products by name. |
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. |
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. It also covers the first import of an account that the Cademí team has not released yet (api_code set to feature_disabled, reason first_import_requires_release). | Read the current state and decide again. For the first import, retrying does not help: contact Cademí support to release it. Later imports are processed normally. |
RATE_LIMITED | Yes | The account reached an API limit. | Wait retry_after_seconds when present, then retry. See Limits, quotas, and retention. |
OPERATION_TIMEOUT | Yes | An API call made by the tool did not finish within the time limit. | Retry. For a call that changes data, retry with the details.idempotency_key of the error (Uncertain results). |
OPERATION_FAILED | No | The call could not be completed for a reason that no other code covers, or it was cancelled. | Retry once, with the details.idempotency_key of the error for a call that changes data. 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. For a call that changes data, 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 OPERATION_TIMEOUT, OPERATION_FAILED, or API_UNAVAILABLE, or with api_code set to idempotency_in_progress, the change may or may not have been applied. The error then brings the key the call used in details.idempotency_key, with retryable: true, and its message says to retry with it. Call the tool again with the same arguments and that idempotency_key: if the first attempt was recorded, the API returns its result and applies nothing new. This works whether you set the key yourself or let the server generate it. 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 a content tree expands a bounded number of modules: a module that was not expanded has children_complete: false.
Time and load
- Time limit. Each API call a tool makes has a time limit. A call that goes over it fails with
OPERATION_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
OPERATION_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.