Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/phpaisdk/core/llms.txt

Use this file to discover all available pages before exploring further.

All errors thrown by the SDK descend from AiSdkException, which extends PHP’s RuntimeException. Every exception carries a structured $context array and a set of typed accessor methods, giving you a consistent interface for reading provider name, HTTP status, request ID, and retry hints — regardless of which provider raised the error. The HttpErrorNormalizer utility maps provider HTTP responses to the appropriate subclass automatically.

Base class: AiSdkException

AiSdkException extends RuntimeException is the root of the exception hierarchy. All SDK exceptions can be caught at this level.

Constructor

message
string
required
Human-readable description of the error.
context
array<string, mixed>
Structured data attached to the exception. Keys such as provider, modelId, status, and retryable are populated by the SDK; specific subclasses add additional keys.
previous
Throwable | null
The original exception that caused this one, used to preserve the full stack trace chain.

Context accessor methods

context()
array<string, mixed>
Returns the raw context array attached to this exception.
provider()
string | null
The identifier of the provider that raised the error (e.g. 'anthropic', 'openai'). null when not set.
modelId()
string | null
The model ID that was in use when the error occurred. null when not set.
status()
int | null
The HTTP status code from the provider’s response. null for non-HTTP errors such as connection failures or SDK-internal exceptions.
requestId()
string | null
The provider-assigned request identifier, when the provider includes one in the response headers or body. Useful for filing support tickets.
errorType()
string | null
The provider-specific error type string, when the response body includes one (e.g. 'invalid_request_error').
errorCode()
string | null
The provider-specific error code string, when the response body includes one (e.g. 'context_length_exceeded').
retryAfter()
int | null
The number of seconds the client should wait before retrying, sourced from a Retry-After header or equivalent body field. null when not provided.
isRetryable()
bool
Returns true when the error is considered safe to retry. The HttpErrorNormalizer sets this for HTTP status codes 408, 409, 429, 500, 502, 503, 504, and 529.
body()
mixed
The raw response body from the provider, either as a decoded array or a raw string depending on the content type. null when not available.

Exception hierarchy

AiSdkException (extends RuntimeException)
├── ProviderException                  — provider returned an error response
│   ├── APIStatusException             — provider returned an HTTP error status
│   │   ├── AuthenticationException    — HTTP 401 — invalid or missing credentials
│   │   ├── PermissionDeniedException  — HTTP 403 — insufficient permissions
│   │   ├── NotFoundException          — HTTP 404 — resource not found
│   │   ├── InvalidRequestException    — HTTP 4xx — malformed or invalid request
│   │   ├── RateLimitException         — HTTP 429 — rate limit exceeded
│   │   ├── OverloadedException        — HTTP 529 — provider capacity exceeded
│   │   └── InternalServerException    — HTTP 5xx — provider server error
│   └── APIConnectionException         — network-level failure, no response received
├── CapabilityNotSupportedException    — requested capability not available on model
├── NoSuchModelException               — model ID not recognised by provider
├── NoSuchToolException                — tool name not registered with the SDK
├── MissingApiKeyException             — API key not configured
├── InvalidArgumentException           — invalid argument passed to an SDK method
├── ToolExecutionException             — tool handler threw during execution
├── InvalidToolInputException          — tool input failed validation
├── JsonException                      — JSON decode failed
└── SchemaValidationException          — structured output failed schema validation

Exception classes

ProviderException

Thrown when a provider returns any error response. The direct parent of all HTTP and connection errors. Catch this class to handle all provider-side failures in a single clause.

APIStatusException

Thrown when the provider returns a non-success HTTP status code. All HTTP-status-specific subclasses extend this class.

AuthenticationException

Thrown for HTTP 401 responses. Indicates that the API key or token is missing, expired, or invalid.

PermissionDeniedException

Thrown for HTTP 403 responses. Indicates that the credentials are valid but lack permission to access the requested resource or model.

NotFoundException

Thrown for HTTP 404 responses. Indicates that the requested resource (endpoint, file, fine-tune, etc.) does not exist on the provider.

InvalidRequestException

Thrown for HTTP 4xx responses not covered by a more specific class. Indicates a malformed request, missing required parameters, or a parameter value outside the allowed range.

RateLimitException

Thrown for HTTP 429 responses. isRetryable() returns true. Check retryAfter() for the number of seconds to wait before retrying.

OverloadedException

Thrown for HTTP 529 responses. Indicates the provider is temporarily over capacity. isRetryable() returns true.

InternalServerException

Thrown for HTTP 5xx responses. Indicates a server-side failure on the provider. isRetryable() returns true for all 5xx codes.

APIConnectionException

Thrown when the HTTP request could not be completed due to a network-level failure — DNS resolution failure, connection timeout, TLS error, etc. No HTTP status code is available. The original transport exception is available via getPrevious().

CapabilityNotSupportedException

Thrown when a requested capability (e.g. Capability::ToolCalling) is not available for the selected model and provider. Constructed via CapabilityNotSupportedException::for() or ::fromSupport().

NoSuchModelException

Thrown when the specified model ID is not recognised by the provider. Constructed via NoSuchModelException::for(string $provider, string $modelId, string $modelType).

NoSuchToolException

Thrown when a tool name is referenced that has not been registered with the SDK. Constructed via NoSuchToolException::for(string $tool).

MissingApiKeyException

Thrown when no API key is configured for a provider. Constructed via MissingApiKeyException::forProvider(string $provider, string $envVar). The message includes the expected environment variable name.

InvalidArgumentException

Thrown when an invalid argument is passed to an SDK method. Extends AiSdkException directly.

ToolExecutionException

Thrown when a registered tool handler throws during execution. The original exception is chained as getPrevious(). Constructed via ToolExecutionException::for(string $tool, Throwable $previous).

InvalidToolInputException

Thrown when a tool’s input arguments fail validation. Has two named constructors: ::missing() for absent required inputs and ::invalid() for inputs of the wrong type or value.

JsonException

Thrown when a JSON decode operation fails. Extends AiSdkException directly.

SchemaValidationException

Thrown when a structured output response fails validation against the provided schema. Extends AiSdkException directly.

Retryable status codes

The following HTTP status codes are marked isRetryable() === true by the HttpErrorNormalizer:
StatusException classReason
408InvalidRequestExceptionRequest timeout — safe to retry.
409InvalidRequestExceptionConflict — transient state, safe to retry.
429RateLimitExceptionRate limit exceeded — back off and retry.
500InternalServerExceptionInternal server error — transient failure.
502InternalServerExceptionBad gateway — transient infrastructure issue.
503InternalServerExceptionService unavailable — transient overload.
504InternalServerExceptionGateway timeout — transient timeout.
529OverloadedExceptionProvider overloaded — back off and retry.

Code example

use AiSdk\Exceptions\AiSdkException;
use AiSdk\Exceptions\AuthenticationException;
use AiSdk\Exceptions\RateLimitException;
use AiSdk\Exceptions\OverloadedException;
use AiSdk\Exceptions\InternalServerException;
use AiSdk\Exceptions\APIConnectionException;
use AiSdk\Exceptions\CapabilityNotSupportedException;
use AiSdk\Exceptions\MissingApiKeyException;
use AiSdk\Exceptions\ToolExecutionException;
use AiSdk\Exceptions\InvalidToolInputException;

try {
    $result = $ai->text('Explain monads to a 10-year-old.');
} catch (MissingApiKeyException $e) {
    // API key not configured — check environment variable
    echo "Set the {$e->context()['envVar']} environment variable.\n";

} catch (AuthenticationException $e) {
    // HTTP 401 — credentials rejected
    echo "Authentication failed for provider {$e->provider()}: {$e->getMessage()}\n";

} catch (RateLimitException $e) {
    // HTTP 429 — wait and retry
    $wait = $e->retryAfter() ?? 60;
    echo "Rate limited. Retrying in {$wait} seconds...\n";
    sleep($wait);

} catch (OverloadedException | InternalServerException $e) {
    // Transient provider failure — retryable
    if ($e->isRetryable()) {
        echo "Transient error (HTTP {$e->status()}) — safe to retry.\n";
    }

} catch (APIConnectionException $e) {
    // Network failure — no HTTP status available
    echo "Network error: {$e->getMessage()}\n";
    echo "Caused by: " . $e->getPrevious()?->getMessage() . "\n";

} catch (CapabilityNotSupportedException $e) {
    // Model does not support the requested capability
    echo "Capability {$e->context()['capability']} unavailable on {$e->modelId()}.\n";

} catch (ToolExecutionException $e) {
    // A tool handler threw — inspect the chain
    echo "Tool '{$e->context()['tool']}' failed: {$e->getMessage()}\n";
    echo "Original exception: " . $e->getPrevious()?->getMessage() . "\n";

} catch (InvalidToolInputException $e) {
    // Tool input validation failed
    $ctx = $e->context();
    echo "Invalid input for tool '{$ctx['tool']}' at path '{$ctx['path']}'.\n";

} catch (AiSdkException $e) {
    // Catch-all for any other SDK exception
    echo "SDK error [{$e->provider()}]: {$e->getMessage()}\n";

    if ($e->requestId() !== null) {
        echo "Request ID for support: {$e->requestId()}\n";
    }
}

Build docs developers (and LLMs) love