Provider and platform failures use one safe envelope:

JSON
{
  "code": "rate_limited",
  "message": "The provider rate limit was reached.",
  "retryable": true,
  "retryAfter": 2,
  "provider": {
    "toolkit": "gmail",
    "status": 429
  }
}

Raw provider bodies and credentials are never part of the public error.

invalid_input

The tool name, JSON body, canonical schema, or provider extension is invalid. Do not retry unchanged. Validate required fields, formats, enum values, and x_provider namespaces.

auth_missing

No usable credential or connection exists for this project, user, and toolkit. Do not retry unchanged. Connect the account, supply the correct connectionId, or configure the service credential.

auth_expired

The provider credential expired or was revoked. Do not loop retries. Refresh or reconnect the account, then start a new attempt.

auth_insufficient_scope

The credential lacks a required provider scope. Do not retry unchanged. Reauthorize with the scopes listed on the generated toolkit page.

not_found

The requested tool, execution, provider object, or scoped route does not exist. Confirm the canonical name and identifier. A resource may also be intentionally invisible across project or user boundaries.

rate_limited

eyeball or the provider rejected excess traffic. This code is retryable. Honor retryAfter seconds when present, use exponential backoff with jitter, and preserve mutation idempotency keys.

provider_unavailable

The provider is temporarily unavailable or returned a transient upstream failure. This code is retryable. Back off, keep the same mutation key, and cap the attempt window.

provider_error

The provider rejected the operation in a way eyeball could not map more narrowly. It is not retryable by default. Inspect the sanitized provider detail, confirm provider constraints, and change the request or account state.

timeout

The request or local wait deadline elapsed. It is not retryable by default because the provider may still have accepted a mutation. Look up the execution first; retry only with the original idempotency key.

not_supported

The selected adapter, deployment, or protocol cannot perform the operation. Examples include the OSS executor without hosted OAuth and MCP async tools before Tasks negotiation. Choose a supported surface; retrying unchanged will not help.

execution_interrupted

A durable worker restarted after provider dispatch may have begun, so the external side effect is ambiguous. Eyeball deliberately does not replay the adapter call. Inspect the provider and reconcile the operation using its business identity or the original idempotency key before starting another execution.

execution_cancelled

The execution was explicitly cancelled. This code is not retryable. Read cancellation.dispatchMayHaveBegun on the execution record: false means provider invocation was durably fenced and reserved usage was released; true means local work was interrupted where possible, but upstream work or external side effects may still complete. Start another execution only when your application has reconciled that ambiguity and intends a new operation.

Default retry policy

Only rate_limited and provider_unavailable default to retryable: true. Every other code defaults to false. Treat the envelope—not HTTP status guesses—as authoritative.

See API error envelopes for HTTP mapping.