Errors and limits

Every failure arrives in the same envelope with a code from a closed set, so an agent can branch on it instead of matching on prose.

{"error":{"code":"provider_not_connected","message":"github is not connected",
  "provider":"github","request_id":"cb6e68fe-542d-4284-9a0f-25018bae6f90"}}

provider, retry_after and reauth_url appear only when they mean something. request_id is always there and is the thing to quote when you ask us about a call.

Over MCP the same envelope comes back as a tool result with isError set, not as a transport error, so the model reads the code and reacts rather than seeing the call vanish.

The codes

  • invalid_credentialThe bearer is missing, unknown or revoked. Not retryable.
  • credential_scope_deniedThe credential is scoped to other providers, or is read only.
  • tool_not_foundNo such tool or provider in this workspace.
  • invalid_argumentsThe arguments do not match the tool input schema.
  • provider_not_connectedNobody has connected that provider yet. Connect it and retry.
  • reauth_requiredThe grant died. Carries reauth_url. A human has to reconnect.
  • quota_exceededThe monthly call quota is spent. Carries retry_after.
  • rate_limitedToo many calls in a minute. Carries retry_after. Retryable.
  • plan_blockedThe plan does not include this tool.
  • upstream_errorThe vendor refused the call. Their reason is in the message.
  • upstream_timeoutThe vendor did not answer in time. Retryable.
  • internal_errorOurs. Quote the request_id.

Limits

A workspace serves at most 60 tools to a client. Past that the list is capped, catalog_truncated says so rather than the list quietly shortening, and selat__search_tools reaches everything the cap left out. The cap exists because agents pick worse tools as the list grows, so a large catalog is a product hazard as much as it is a feature.

Calls are rate limited per workspace and counted against the monthly quota on your plan. Discovery is not counted: listing tools and searching them are free.