Skip to content
Effect 4.0 is here. One ecosystem. Zero dependencies.

AiError unstable

Defines shared errors for AI operations.

AiError records where a failure happened and stores the detailed reason in a reason field. Those reasons cover transport problems, provider responses, rate limits, authentication, content policy failures, invalid requests, invalid output, unsupported schemas, tool failures, invalid user input, and unknown failures. This module also includes metadata schemas, guards, constructors, and helpers for converting HTTP response information into AI error reasons.

43 exports Since v4.0.0 Source

Configuration

Since v4.0.0

Provider-specific metadata attached to AuthenticationError.

Signature

interface AuthenticationErrorMetadata extends ProviderMetadata {
[key: string]: MutableJson;
}

ContentPolicyErrorMetadata

interface unstable
Since v4.0.0

Provider-specific metadata attached to ContentPolicyError.

Signature

interface ContentPolicyErrorMetadata extends ProviderMetadata {
[key: string]: MutableJson;
}
Since v4.0.0

Provider-specific metadata attached to InternalProviderError.

Signature

interface InternalProviderErrorMetadata extends ProviderMetadata {
[key: string]: MutableJson;
}

InvalidOutputErrorMetadata

interface unstable
Since v4.0.0

Provider-specific metadata attached to InvalidOutputError.

Signature

interface InvalidOutputErrorMetadata extends ProviderMetadata {
[key: string]: MutableJson;
}
Since v4.0.0

Provider-specific metadata attached to InvalidRequestError.

Signature

interface InvalidRequestErrorMetadata extends ProviderMetadata {
[key: string]: MutableJson;
}
Since v4.0.0

Provider-specific metadata attached to QuotaExhaustedError.

Signature

interface QuotaExhaustedErrorMetadata extends ProviderMetadata {
[key: string]: MutableJson;
}

RateLimitErrorMetadata

interface unstable
Since v4.0.0

Provider-specific metadata attached to RateLimitError.

Signature

interface RateLimitErrorMetadata extends ProviderMetadata {
[key: string]: MutableJson;
}
Since v4.0.0

Provider-specific metadata attached to StructuredOutputError.

Signature

interface StructuredOutputErrorMetadata extends ProviderMetadata {
[key: string]: MutableJson;
}

UnknownErrorMetadata

interface unstable
Since v4.0.0

Provider-specific metadata attached to UnknownError.

Signature

interface UnknownErrorMetadata extends ProviderMetadata {
[key: string]: MutableJson;
}
Since v4.0.0

Provider-specific metadata attached to UnsupportedSchemaError.

Signature

interface UnsupportedSchemaErrorMetadata extends ProviderMetadata {
[key: string]: MutableJson;
}

Constructors

make

unstable
Since v4.0.0

Creates an AiError with the given reason.

Signature

declare function make(params: {
readonly method: string;
readonly module: string;
readonly reason: AiErrorReason;
}): AiError

Example Creating an AI error

import { Duration } from "effect"
import { AiError } from "effect/ai"
const error = AiError.make({
module: "OpenAI",
method: "completion",
reason: new AiError.RateLimitError({
retryAfter: Duration.seconds(60)
})
})
const result = [error.module, error.method, error.reason._tag] // => ["OpenAI", "completion", "RateLimitError"]
Since v4.0.0

Maps HTTP status codes to semantic error reasons.

When to use

Use as the base mapping when provider packages translate HTTP status codes into provider-specific error reasons.

Signature

declare function reasonFromHttpStatus(params: {
readonly body?: unknown;
readonly description?: string;
readonly http?: {
readonly body?: string;
readonly request: {
readonly hash?: string;
readonly headers: {
[key: string]: string | Redacted<string>;
};
readonly method: "GET" | "POST" | "PATCH" | "PUT" | "DELETE" | "HEAD" | "OPTIONS" | "TRACE" | "QUERY";
readonly url: string;
readonly urlParams: readonly Array<readonly [string, string | Redacted<string>]>;
};
readonly response?: {
readonly headers: {
[key: string]: string | Redacted<string>;
};
readonly status: number;
};
};
readonly metadata?: {
[key: string]: MutableJson;
};
readonly status: number;
}): AiErrorReason

Example Mapping an HTTP status to a reason

import { AiError } from "effect/ai"
const reason = AiError.reasonFromHttpStatus({
status: 429,
body: { error: "Rate limit exceeded" }
})
reason._tag // => "RateLimitError"

Errors

AiErrorReason

type unstable
Since v4.0.0

Union type of all semantic error reasons that can occur during AI operations.

Details

Every reason carries a semantic _tag, a human-readable message, and an isRetryable getter. Provider-facing reasons may also include retry timing, provider metadata, usage information, or HTTP context.

Signature

type AiErrorReason = RateLimitError | QuotaExhaustedError | AuthenticationError | ContentPolicyError | InvalidRequestError | InternalProviderError | NetworkError | InvalidOutputError | StructuredOutputError | UnsupportedSchemaError | UnknownError | ToolNotFoundError | ToolParameterValidationError | InvalidToolResultError | ToolResultEncodingError | ToolConfigurationError | ToolkitRequiredError | InvalidUserInputError
Since v4.0.0

Error indicating authentication or authorization failure.

Details

Authentication errors are never retryable without credential changes.

Signature

declare class AuthenticationError extends {
readonly _tag: "AuthenticationError";
readonly description?: string;
readonly http?: {
readonly body?: string;
readonly request: {
readonly hash?: string;
readonly headers: {
[key: string]: string | Redacted<string>;
};
readonly method: "GET" | "POST" | "PATCH" | "PUT" | "DELETE" | "HEAD" | "OPTIONS" | "TRACE" | "QUERY";
readonly url: string;
readonly urlParams: readonly Array<readonly [string, string | Redacted<string>]>;
};
readonly response?: {
readonly headers: {
[key: string]: string | Redacted<string>;
};
readonly status: number;
};
};
readonly kind: "Unknown" | "MissingKey" | "InvalidKey" | "ExpiredKey" | "InsufficientPermissions";
readonly metadata: {
[key: string]: MutableJson;
} & AuthenticationErrorMetadata;
} & YieldableError<this> {
constructor(...args: [props: {
readonly _tag?: "AuthenticationError";
readonly description?: string;
readonly http?: {
readonly body?: string;
readonly request: {
readonly hash?: string;
readonly headers: {
[key: string]: string | Redacted<string>;
};
readonly method: "GET" | "POST" | "PATCH" | "PUT" | "DELETE" | "HEAD" | "OPTIONS" | "TRACE" | "QUERY";
readonly url: string;
readonly urlParams: readonly Array<readonly [string, string | Redacted<string>]>;
};
readonly response?: {
readonly headers: {
[key: string]: string | Redacted<string>;
};
readonly status: number;
};
};
readonly kind: "Unknown" | "MissingKey" | "InvalidKey" | "ExpiredKey" | "InsufficientPermissions";
readonly metadata?: {
[key: string]: unknown;
};
}, options?: MakeOptions]);
readonly "~effect/ai/AiError/Reason": "~effect/ai/AiError/Reason";
isRetryable: boolean;
message: string;
}

Example Creating an authentication error

import { AiError } from "effect/ai"
const authError = new AiError.AuthenticationError({
kind: "InvalidKey"
})
const result = [authError.kind, authError.isRetryable] // => ["InvalidKey", false]
const detailed = new AiError.AuthenticationError({
kind: "InsufficientPermissions",
description: "Token expired"
})
detailed.message // => "InsufficientPermissions: Your API key lacks required permissions. Token expired"
Since v4.0.0

Error indicating content policy violation.

Details

Content policy errors are never retryable without content changes.

Signature

declare class ContentPolicyError extends {
readonly _tag: "ContentPolicyError";
readonly description: string;
readonly http?: {
readonly body?: string;
readonly request: {
readonly hash?: string;
readonly headers: {
[key: string]: string | Redacted<string>;
};
readonly method: "GET" | "POST" | "PATCH" | "PUT" | "DELETE" | "HEAD" | "OPTIONS" | "TRACE" | "QUERY";
readonly url: string;
readonly urlParams: readonly Array<readonly [string, string | Redacted<string>]>;
};
readonly response?: {
readonly headers: {
[key: string]: string | Redacted<string>;
};
readonly status: number;
};
};
readonly metadata: {
[key: string]: MutableJson;
} & ContentPolicyErrorMetadata;
} & YieldableError<this> {
constructor(...args: [props: {
readonly _tag?: "ContentPolicyError";
readonly description: string;
readonly http?: {
readonly body?: string;
readonly request: {
readonly hash?: string;
readonly headers: {
[key: string]: string | Redacted<string>;
};
readonly method: "GET" | "POST" | "PATCH" | "PUT" | "DELETE" | "HEAD" | "OPTIONS" | "TRACE" | "QUERY";
readonly url: string;
readonly urlParams: readonly Array<readonly [string, string | Redacted<string>]>;
};
readonly response?: {
readonly headers: {
[key: string]: string | Redacted<string>;
};
readonly status: number;
};
};
readonly metadata?: {
[key: string]: unknown;
};
}, options?: MakeOptions]);
readonly "~effect/ai/AiError/Reason": "~effect/ai/AiError/Reason";
isRetryable: boolean;
message: string;
}

Example Creating a content policy error

import { AiError } from "effect/ai"
const policyError = new AiError.ContentPolicyError({
description: "Input contains prohibited content"
})
const result = [policyError.description, policyError.isRetryable] // => ["Input contains prohibited content", false]
Since v4.0.0

Error indicating the AI provider experienced an internal error.

Details

Internal provider errors are typically transient and are retryable.

Signature

declare class InternalProviderError extends {
readonly _tag: "InternalProviderError";
readonly description: string;
readonly http?: {
readonly body?: string;
readonly request: {
readonly hash?: string;
readonly headers: {
[key: string]: string | Redacted<string>;
};
readonly method: "GET" | "POST" | "PATCH" | "PUT" | "DELETE" | "HEAD" | "OPTIONS" | "TRACE" | "QUERY";
readonly url: string;
readonly urlParams: readonly Array<readonly [string, string | Redacted<string>]>;
};
readonly response?: {
readonly headers: {
[key: string]: string | Redacted<string>;
};
readonly status: number;
};
};
readonly metadata: {
[key: string]: MutableJson;
} & InternalProviderErrorMetadata;
} & YieldableError<this> {
constructor(...args: [props: {
readonly _tag?: "InternalProviderError";
readonly description: string;
readonly http?: {
readonly body?: string;
readonly request: {
readonly hash?: string;
readonly headers: {
[key: string]: string | Redacted<string>;
};
readonly method: "GET" | "POST" | "PATCH" | "PUT" | "DELETE" | "HEAD" | "OPTIONS" | "TRACE" | "QUERY";
readonly url: string;
readonly urlParams: readonly Array<readonly [string, string | Redacted<string>]>;
};
readonly response?: {
readonly headers: {
[key: string]: string | Redacted<string>;
};
readonly status: number;
};
};
readonly metadata?: {
[key: string]: unknown;
};
}, options?: MakeOptions]);
readonly "~effect/ai/AiError/Reason": "~effect/ai/AiError/Reason";
isRetryable: boolean;
message: string;
}

Example Creating an internal provider error

import { AiError } from "effect/ai"
const providerError = new AiError.InternalProviderError({
description: "Server encountered an unexpected error"
})
const result = [providerError.description, providerError.isRetryable] // => ["Server encountered an unexpected error", true]
Since v4.0.0

Error indicating failure to parse or validate LLM output.

Details

Invalid output errors are retryable since LLM outputs are non-deterministic.

Signature

declare class InvalidOutputError extends {
readonly _tag: "InvalidOutputError";
readonly description: string;
readonly metadata: {
[key: string]: MutableJson;
} & InvalidOutputErrorMetadata;
readonly usage?: {
readonly completionTokens?: number;
readonly promptTokens?: number;
readonly totalTokens?: number;
};
} & YieldableError<this> {
constructor(...args: [props: {
readonly _tag?: "InvalidOutputError";
readonly description: string;
readonly metadata?: {
[key: string]: unknown;
};
readonly usage?: {
readonly completionTokens?: number;
readonly promptTokens?: number;
readonly totalTokens?: number;
};
}, options?: MakeOptions]);
readonly "~effect/ai/AiError/Reason": "~effect/ai/AiError/Reason";
isRetryable: boolean;
message: string;
static fromSchemaError(error: SchemaError): InvalidOutputError;
}

Example Creating an invalid output error

import { AiError } from "effect/ai"
const parseError = new AiError.InvalidOutputError({
description: "Expected a string but received a number"
})
const result = [parseError.description, parseError.isRetryable] // => ["Expected a string but received a number", true]
Since v4.0.0

Error indicating the request had invalid or malformed parameters.

Details

Invalid request errors require fixing the request and are not retryable.

Signature

declare class InvalidRequestError extends {
readonly _tag: "InvalidRequestError";
readonly constraint?: string;
readonly description?: string;
readonly http?: {
readonly body?: string;
readonly request: {
readonly hash?: string;
readonly headers: {
[key: string]: string | Redacted<string>;
};
readonly method: "GET" | "POST" | "PATCH" | "PUT" | "DELETE" | "HEAD" | "OPTIONS" | "TRACE" | "QUERY";
readonly url: string;
readonly urlParams: readonly Array<readonly [string, string | Redacted<string>]>;
};
readonly response?: {
readonly headers: {
[key: string]: string | Redacted<string>;
};
readonly status: number;
};
};
readonly metadata: {
[key: string]: MutableJson;
} & InvalidRequestErrorMetadata;
readonly parameter?: string;
} & YieldableError<this> {
constructor(...args: [props?: {
readonly _tag?: "InvalidRequestError";
readonly constraint?: string;
readonly description?: string;
readonly http?: {
readonly body?: string;
readonly request: {
readonly hash?: string;
readonly headers: {
[key: string]: string | Redacted<string>;
};
readonly method: "GET" | "POST" | "PATCH" | "PUT" | "DELETE" | "HEAD" | "OPTIONS" | "TRACE" | "QUERY";
readonly url: string;
readonly urlParams: readonly Array<readonly [string, string | Redacted<string>]>;
};
readonly response?: {
readonly headers: {
[key: string]: string | Redacted<string>;
};
readonly status: number;
};
};
readonly metadata?: {
[key: string]: unknown;
};
readonly parameter?: string;
}, options?: MakeOptions]);
readonly "~effect/ai/AiError/Reason": "~effect/ai/AiError/Reason";
isRetryable: boolean;
message: string;
}

Example Creating an invalid request error

import { AiError } from "effect/ai"
const invalidRequestError = new AiError.InvalidRequestError({
parameter: "temperature",
constraint: "must be between 0 and 2",
description: "Temperature value 5 is out of range"
})
const result = [invalidRequestError.parameter, invalidRequestError.isRetryable] // => ["temperature", false]

Error indicating the tool handler returned an invalid result that does not match the tool's schema.

Details

This error is not retryable because invalid results indicate a bug in the tool handler implementation.

Signature

declare class InvalidToolResultError extends {
readonly _tag: "InvalidToolResultError";
readonly description: string;
readonly toolName: string;
} & YieldableError<this> {
constructor(...args: [props: {
readonly _tag?: "InvalidToolResultError";
readonly description: string;
readonly toolName: string;
}, options?: MakeOptions]);
readonly "~effect/ai/AiError/Reason": "~effect/ai/AiError/Reason";
isRetryable: boolean;
message: string;
}

Example Creating an invalid tool result error

import { AiError } from "effect/ai"
const error = new AiError.InvalidToolResultError({
toolName: "GetWeather",
description: "Tool handler returned invalid result: missing 'temperature' field"
})
const result = [error.toolName, error.isRetryable] // => ["GetWeather", false]
Since v4.0.0

Error indicating the user provided invalid input in their prompt.

Details

This error is raised when the prompt contains content that is structurally valid but not supported by the provider (e.g., unsupported media types, unsupported file formats, etc.).

Signature

declare class InvalidUserInputError extends {
readonly _tag: "InvalidUserInputError";
readonly description: string;
} & YieldableError<this> {
constructor(...args: [props: {
readonly _tag?: "InvalidUserInputError";
readonly description: string;
}, options?: MakeOptions]);
readonly "~effect/ai/AiError/Reason": "~effect/ai/AiError/Reason";
isRetryable: boolean;
message: string;
}

Example Creating an invalid user input error

import { AiError } from "effect/ai"
const error = new AiError.InvalidUserInputError({
description: "Unsupported media type 'video/mp4'. Supported types include images, application/pdf, text/plain"
})
const result = [error._tag, error.isRetryable] // => ["InvalidUserInputError", false]
Since v4.0.0

Error indicating a network-level failure before receiving a response.

Details

This error is raised when issues arise before receiving an HTTP response, such as network connectivity problems, request encoding issues, or invalid URLs.

Signature

declare class NetworkError extends {
readonly _tag: "NetworkError";
readonly description?: string;
readonly reason: "TransportError" | "EncodeError" | "InvalidUrlError";
readonly request: {
readonly hash?: string;
readonly headers: {
[key: string]: string | Redacted<string>;
};
readonly method: "GET" | "POST" | "PATCH" | "PUT" | "DELETE" | "HEAD" | "OPTIONS" | "TRACE" | "QUERY";
readonly url: string;
readonly urlParams: readonly Array<readonly [string, string | Redacted<string>]>;
};
} & YieldableError<this> {
constructor(...args: [props: {
readonly _tag?: "NetworkError";
readonly description?: string;
readonly reason: "TransportError" | "EncodeError" | "InvalidUrlError";
readonly request: {
readonly hash?: string;
readonly headers: {
[key: string]: string | Redacted<string>;
};
readonly method: "GET" | "POST" | "PATCH" | "PUT" | "DELETE" | "HEAD" | "OPTIONS" | "TRACE" | "QUERY";
readonly url: string;
readonly urlParams: readonly Array<readonly [string, string | Redacted<string>]>;
};
}, options?: MakeOptions]);
readonly "~effect/ai/AiError/Reason": "~effect/ai/AiError/Reason";
isRetryable: boolean;
message: string;
static fromRequestError(error: RequestError): NetworkError;
}

Example Creating a network error

import { AiError } from "effect/ai"
const error = new AiError.NetworkError({
reason: "TransportError",
request: {
method: "POST",
url: "https://api.openai.com/v1/completions",
urlParams: [],
hash: undefined,
headers: { "Content-Type": "application/json" }
},
description: "Connection timeout after 30 seconds"
})
const result = [error.reason, error.isRetryable] // => ["TransportError", true]
Since v4.0.0

Error indicating account or billing limits have been reached.

Details

Quota exhausted errors are not retryable without user action.

Signature

declare class QuotaExhaustedError extends {
readonly _tag: "QuotaExhaustedError";
readonly http?: {
readonly body?: string;
readonly request: {
readonly hash?: string;
readonly headers: {
[key: string]: string | Redacted<string>;
};
readonly method: "GET" | "POST" | "PATCH" | "PUT" | "DELETE" | "HEAD" | "OPTIONS" | "TRACE" | "QUERY";
readonly url: string;
readonly urlParams: readonly Array<readonly [string, string | Redacted<string>]>;
};
readonly response?: {
readonly headers: {
[key: string]: string | Redacted<string>;
};
readonly status: number;
};
};
readonly metadata: {
[key: string]: MutableJson;
} & QuotaExhaustedErrorMetadata;
readonly resetAt?: Utc;
} & YieldableError<this> {
constructor(...args: [props?: {
readonly _tag?: "QuotaExhaustedError";
readonly http?: {
readonly body?: string;
readonly request: {
readonly hash?: string;
readonly headers: {
[key: string]: string | Redacted<string>;
};
readonly method: "GET" | "POST" | "PATCH" | "PUT" | "DELETE" | "HEAD" | "OPTIONS" | "TRACE" | "QUERY";
readonly url: string;
readonly urlParams: readonly Array<readonly [string, string | Redacted<string>]>;
};
readonly response?: {
readonly headers: {
[key: string]: string | Redacted<string>;
};
readonly status: number;
};
};
readonly metadata?: {
[key: string]: unknown;
};
readonly resetAt?: Utc;
}, options?: MakeOptions]);
readonly "~effect/ai/AiError/Reason": "~effect/ai/AiError/Reason";
isRetryable: boolean;
message: string;
}

Example Creating a quota exhausted error

import { AiError } from "effect/ai"
const quotaError = new AiError.QuotaExhaustedError({})
const result = [quotaError._tag, quotaError.isRetryable] // => ["QuotaExhaustedError", false]
Since v4.0.0

Error indicating the request was rate limited.

Details

Rate limit errors are always retryable. When retryAfter is provided, callers should wait that duration before retrying.

Signature

declare class RateLimitError extends {
readonly _tag: "RateLimitError";
readonly http?: {
readonly body?: string;
readonly request: {
readonly hash?: string;
readonly headers: {
[key: string]: string | Redacted<string>;
};
readonly method: "GET" | "POST" | "PATCH" | "PUT" | "DELETE" | "HEAD" | "OPTIONS" | "TRACE" | "QUERY";
readonly url: string;
readonly urlParams: readonly Array<readonly [string, string | Redacted<string>]>;
};
readonly response?: {
readonly headers: {
[key: string]: string | Redacted<string>;
};
readonly status: number;
};
};
readonly metadata: {
[key: string]: MutableJson;
} & RateLimitErrorMetadata;
readonly retryAfter?: Duration;
} & YieldableError<this> {
constructor(...args: [props?: {
readonly _tag?: "RateLimitError";
readonly http?: {
readonly body?: string;
readonly request: {
readonly hash?: string;
readonly headers: {
[key: string]: string | Redacted<string>;
};
readonly method: "GET" | "POST" | "PATCH" | "PUT" | "DELETE" | "HEAD" | "OPTIONS" | "TRACE" | "QUERY";
readonly url: string;
readonly urlParams: readonly Array<readonly [string, string | Redacted<string>]>;
};
readonly response?: {
readonly headers: {
[key: string]: string | Redacted<string>;
};
readonly status: number;
};
};
readonly metadata?: {
[key: string]: unknown;
};
readonly retryAfter?: Duration;
}, options?: MakeOptions]);
readonly "~effect/ai/AiError/Reason": "~effect/ai/AiError/Reason";
isRetryable: boolean;
message: string;
}

Example Creating a rate limit error

import { Duration } from "effect"
import { AiError } from "effect/ai"
const rateLimitError = new AiError.RateLimitError({
retryAfter: Duration.seconds(60)
})
const result = [rateLimitError._tag, rateLimitError.isRetryable] // => ["RateLimitError", true]
Since v4.0.0

Error indicating the LLM generated text that does not conform to the requested structured output schema.

Details

Structured output errors are retryable since LLM outputs are non-deterministic.

Signature

declare class StructuredOutputError extends {
readonly _tag: "StructuredOutputError";
readonly description: string;
readonly metadata: {
[key: string]: MutableJson;
} & StructuredOutputErrorMetadata;
readonly responseText: string;
readonly usage?: {
readonly completionTokens?: number;
readonly promptTokens?: number;
readonly totalTokens?: number;
};
} & YieldableError<this> {
constructor(...args: [props: {
readonly _tag?: "StructuredOutputError";
readonly description: string;
readonly metadata?: {
[key: string]: unknown;
};
readonly responseText: string;
readonly usage?: {
readonly completionTokens?: number;
readonly promptTokens?: number;
readonly totalTokens?: number;
};
}, options?: MakeOptions]);
readonly "~effect/ai/AiError/Reason": "~effect/ai/AiError/Reason";
isRetryable: boolean;
message: string;
static fromSchemaError(error: SchemaError, responseText: string): StructuredOutputError;
}

Example Creating a structured output error

import { AiError } from "effect/ai"
const error = new AiError.StructuredOutputError({
description: "Expected a valid JSON object",
responseText: "{\"foo\":}"
})
const result = [error.description, error.responseText, error.isRetryable] // => ["Expected a valid JSON object", '{"foo":}', true]

Error indicating a provider-defined tool was configured with invalid arguments.

Details

This error is not retryable because it indicates a programming error in the tool configuration that must be fixed in code.

Signature

declare class ToolConfigurationError extends {
readonly _tag: "ToolConfigurationError";
readonly description: string;
readonly toolName: string;
} & YieldableError<this> {
constructor(...args: [props: {
readonly _tag?: "ToolConfigurationError";
readonly description: string;
readonly toolName: string;
}, options?: MakeOptions]);
readonly "~effect/ai/AiError/Reason": "~effect/ai/AiError/Reason";
isRetryable: boolean;
message: string;
}

Example Creating a tool configuration error

import { AiError } from "effect/ai"
const error = new AiError.ToolConfigurationError({
toolName: "OpenAiCodeInterpreter",
description: "Invalid container ID format"
})
const result = [error.toolName, error.description, error.isRetryable] // => ["OpenAiCodeInterpreter", "Invalid container ID format", false]
Since v4.0.0

Error indicating an operation requires a toolkit but none was provided.

Details

This error occurs when tool approval responses are present in the prompt but no toolkit was provided to resolve them.

Signature

declare class ToolkitRequiredError extends {
readonly _tag: "ToolkitRequiredError";
readonly description?: string;
readonly pendingApprovals: readonly Array<string>;
} & YieldableError<this> {
constructor(...args: [props: {
readonly _tag?: "ToolkitRequiredError";
readonly description?: string;
readonly pendingApprovals: readonly Array<string>;
}, options?: MakeOptions]);
readonly "~effect/ai/AiError/Reason": "~effect/ai/AiError/Reason";
isRetryable: boolean;
message: string;
}

Example Creating a toolkit required error

import { AiError } from "effect/ai"
const error = new AiError.ToolkitRequiredError({
pendingApprovals: ["GetWeather", "SendEmail"]
})
const result = [error.pendingApprovals, error.isRetryable] // => [["GetWeather", "SendEmail"], false]
Since v4.0.0

Error indicating the model requested a tool that doesn't exist in the toolkit.

Details

This error is retryable because the model may self-correct when provided with the list of available tools.

Signature

declare class ToolNotFoundError extends {
readonly _tag: "ToolNotFoundError";
readonly availableTools: readonly Array<string>;
readonly toolName: string;
} & YieldableError<this> {
constructor(...args: [props: {
readonly _tag?: "ToolNotFoundError";
readonly availableTools: readonly Array<string>;
readonly toolName: string;
}, options?: MakeOptions]);
readonly "~effect/ai/AiError/Reason": "~effect/ai/AiError/Reason";
isRetryable: boolean;
message: string;
}

Example Creating a tool not found error

import { AiError } from "effect/ai"
const error = new AiError.ToolNotFoundError({
toolName: "unknownTool",
availableTools: ["GetWeather", "GetTime"]
})
const result = [error.toolName, error.availableTools, error.isRetryable] // => ["unknownTool", ["GetWeather", "GetTime"], true]

Error indicating the model's tool call parameters failed schema validation.

Details

This error is retryable because the model may correct its parameters on subsequent attempts.

Signature

declare class ToolParameterValidationError extends {
readonly _tag: "ToolParameterValidationError";
readonly description: string;
readonly toolName: string;
} & YieldableError<this> {
constructor(...args: [props: {
readonly _tag?: "ToolParameterValidationError";
readonly description: string;
readonly toolName: string;
}, options?: MakeOptions]);
readonly "~effect/ai/AiError/Reason": "~effect/ai/AiError/Reason";
isRetryable: boolean;
message: string;
}

Example Creating a tool parameter validation error

import { AiError } from "effect/ai"
const error = new AiError.ToolParameterValidationError({
toolName: "GetWeather",
description: "Expected string, got number"
})
const result = [error.toolName, error.description, error.isRetryable] // => ["GetWeather", "Expected string, got number", true]

Error indicating the tool result cannot be encoded for sending back to the model.

Details

This error is not retryable because encoding failures indicate a bug in the tool schema definitions.

Signature

declare class ToolResultEncodingError extends {
readonly _tag: "ToolResultEncodingError";
readonly description: string;
readonly toolName: string;
readonly toolResult: unknown;
} & YieldableError<this> {
constructor(...args: [props: {
readonly _tag?: "ToolResultEncodingError";
readonly description: string;
readonly toolName: string;
readonly toolResult: unknown;
}, options?: MakeOptions]);
readonly "~effect/ai/AiError/Reason": "~effect/ai/AiError/Reason";
isRetryable: boolean;
message: string;
}

Example Creating a tool result encoding error

import { AiError } from "effect/ai"
const error = new AiError.ToolResultEncodingError({
toolName: "GetWeather",
toolResult: { temperature: 72n },
description: "Cannot encode bigint values as JSON"
})
const result = [error.toolName, error.description, error.isRetryable] // => ["GetWeather", "Cannot encode bigint values as JSON", false]
Since v4.0.0

Error data for unknown or unexpected AI failures.

Details

Unknown errors are not retryable by default since the cause is unknown.

Signature

declare class UnknownError extends {
readonly _tag: "UnknownError";
readonly description?: string;
readonly http?: {
readonly body?: string;
readonly request: {
readonly hash?: string;
readonly headers: {
[key: string]: string | Redacted<string>;
};
readonly method: "GET" | "POST" | "PATCH" | "PUT" | "DELETE" | "HEAD" | "OPTIONS" | "TRACE" | "QUERY";
readonly url: string;
readonly urlParams: readonly Array<readonly [string, string | Redacted<string>]>;
};
readonly response?: {
readonly headers: {
[key: string]: string | Redacted<string>;
};
readonly status: number;
};
};
readonly metadata: {
[key: string]: MutableJson;
} & UnknownErrorMetadata;
} & YieldableError<this> {
constructor(...args: [props?: {
readonly _tag?: "UnknownError";
readonly description?: string;
readonly http?: {
readonly body?: string;
readonly request: {
readonly hash?: string;
readonly headers: {
[key: string]: string | Redacted<string>;
};
readonly method: "GET" | "POST" | "PATCH" | "PUT" | "DELETE" | "HEAD" | "OPTIONS" | "TRACE" | "QUERY";
readonly url: string;
readonly urlParams: readonly Array<readonly [string, string | Redacted<string>]>;
};
readonly response?: {
readonly headers: {
[key: string]: string | Redacted<string>;
};
readonly status: number;
};
};
readonly metadata?: {
[key: string]: unknown;
};
}, options?: MakeOptions]);
readonly "~effect/ai/AiError/Reason": "~effect/ai/AiError/Reason";
isRetryable: boolean;
message: string;
}

Example Creating an unknown error

import { AiError } from "effect/ai"
const unknownError = new AiError.UnknownError({
description: "An unexpected error occurred"
})
const result = [unknownError.description, unknownError.isRetryable] // => ["An unexpected error occurred", false]

Error indicating a codec transformer rejected a schema because it contains unsupported constructs.

Details

Unsupported schema errors are not retryable because they indicate a programmer error where the schema is incompatible with the provider.

Signature

declare class UnsupportedSchemaError extends {
readonly _tag: "UnsupportedSchemaError";
readonly description: string;
readonly metadata: {
[key: string]: MutableJson;
} & UnsupportedSchemaErrorMetadata;
} & YieldableError<this> {
constructor(...args: [props: {
readonly _tag?: "UnsupportedSchemaError";
readonly description: string;
readonly metadata?: {
[key: string]: unknown;
};
}, options?: MakeOptions]);
readonly "~effect/ai/AiError/Reason": "~effect/ai/AiError/Reason";
isRetryable: boolean;
message: string;
}

Example Creating an unsupported schema error

import { AiError } from "effect/ai"
const error = new AiError.UnsupportedSchemaError({
description: "Unions are not supported in Anthropic structured output"
})
const result = [error.description, error.isRetryable] // => ["Unions are not supported in Anthropic structured output", false]

Guards

isAiError

unstable
Since v4.0.0

Type guard to check if a value is an AiError.

Signature

declare function isAiError(u: unknown): u is AiError

Example Checking for an AI error

import { AiError } from "effect/ai"
const someError = new Error("generic error")
const aiError = AiError.make({
module: "Test",
method: "example",
reason: new AiError.RateLimitError({})
})
const result = [AiError.isAiError(someError), AiError.isAiError(aiError)] // => [false, true]
Since v4.0.0

Type guard to check if a value is an AiErrorReason.

Signature

declare function isAiErrorReason(u: unknown): u is AiErrorReason

Example Checking for an AI error reason

import { AiError } from "effect/ai"
const rateLimitError = new AiError.RateLimitError({})
const genericError = new Error("generic error")
const result = [AiError.isAiErrorReason(rateLimitError), AiError.isAiErrorReason(genericError)] // => [true, false]

Models

ProviderMetadata

type unstable
Since v4.0.0

Type of provider-specific metadata attached to AI error reasons.

Details

Metadata is keyed by provider name, and each provider value is either mutable JSON metadata or null.

Signature

type ProviderMetadata = typeof ProviderMetadata.Type

Schemas

AiError

unstable
Since v4.0.0

Schema for the top-level AI error wrapper using the reason pattern.

When to use

Use when you need AI errors that can be handled by semantic reason with Effect.catchReason.

Details

This error stores module and method context, the semantic reason, and delegates isRetryable and retryAfter to the underlying reason.

Signature

declare class AiError extends {
readonly _tag: "AiError";
readonly method: string;
readonly module: string;
readonly reason: NetworkError | RateLimitError | QuotaExhaustedError | AuthenticationError | ContentPolicyError | InvalidRequestError | InternalProviderError | InvalidOutputError | StructuredOutputError | UnsupportedSchemaError | UnknownError | ToolNotFoundError | ToolParameterValidationError | InvalidToolResultError | ToolResultEncodingError | ToolConfigurationError | ToolkitRequiredError | InvalidUserInputError;
} & YieldableError<this> {
constructor(...args: [props: {
readonly _tag?: "AiError";
readonly method: string;
readonly module: string;
readonly reason: NetworkError | RateLimitError | QuotaExhaustedError | AuthenticationError | ContentPolicyError | InvalidRequestError | InternalProviderError | InvalidOutputError | StructuredOutputError | UnsupportedSchemaError | UnknownError | ToolNotFoundError | ToolParameterValidationError | InvalidToolResultError | ToolResultEncodingError | ToolConfigurationError | ToolkitRequiredError | InvalidUserInputError;
}, options?: MakeOptions]);
readonly "~effect/ai/AiError": "~effect/ai/AiError";
readonly cause: NetworkError | RateLimitError | QuotaExhaustedError | AuthenticationError | ContentPolicyError | InvalidRequestError | InternalProviderError | InvalidOutputError | StructuredOutputError | UnsupportedSchemaError | UnknownError | ToolNotFoundError | ToolParameterValidationError | InvalidToolResultError | ToolResultEncodingError | ToolConfigurationError | ToolkitRequiredError | InvalidUserInputError;
isRetryable: boolean;
message: string;
retryAfter: Duration | undefined;
}

Example Handling an AI error by tag

import { Duration, Effect } from "effect"
import { AiError } from "effect/ai"
const aiOperation = Effect.fail(new AiError.AiError({
module: "OpenAI",
method: "generateText",
reason: new AiError.RateLimitError({ retryAfter: Duration.seconds(30) })
}))
// Handle specific reason types
const handled = aiOperation.pipe(
Effect.catchTag("AiError", (error) => {
if (error.reason._tag === "RateLimitError") {
return Effect.succeed(`Retry after ${error.retryAfter}`)
}
return Effect.fail(error)
})
)
await Effect.runPromise(handled) // => "Retry after 30000 millis"

AiErrorEncoded

type unstable
Since v4.0.0

The encoded (serialized) form of an AiError.

Signature

type AiErrorEncoded = typeof AiError["Encoded"]
Since v4.0.0

Schema for validating and parsing AI error reasons.

When to use

Use when decoding or validating unknown AI error reason values with Schema.

Details

This runtime schema is the union of the concrete AI error reason classes.

See

Signature

declare const AiErrorReason: Union<[typeof RateLimitError, typeof QuotaExhaustedError, typeof AuthenticationError, typeof ContentPolicyError, typeof InvalidRequestError, typeof InternalProviderError, typeof NetworkError]>

HttpContext

unstable
Since v4.0.0

Schema for the combined HTTP context used in error reporting.

When to use

Use to attach request details, optional response details, and optional body text to AI provider errors.

Details

Includes the required request details plus optional response details and raw response body.

See

Signature

declare const HttpContext: Struct<{
readonly body: optional<String>;
readonly request: Struct<{
readonly hash: optional<String>;
readonly headers: $Record<String, Union<readonly [String, Redacted<String>]>>;
readonly method: Literals<readonly ["GET", "POST", "PATCH", "PUT", "DELETE", "HEAD", "OPTIONS", "TRACE", "QUERY"]>;
readonly url: String;
readonly urlParams: $Array<Tuple<readonly [String, Union<readonly [String, Redacted<String>]>]>>;
}>;
readonly response: optional<Struct<{
readonly headers: $Record<String, Union<readonly [String, Redacted<String>]>>;
readonly status: Int;
}>>;
}>
Since v4.0.0

Schema for HTTP requests to an AI provider.

Signature

declare const HttpRequestDetails: Struct<{
readonly hash: optional<String>;
readonly headers: $Record<String, Union<readonly [String, Redacted<String>]>>;
readonly method: Literals<readonly ["GET", "POST", "PATCH", "PUT", "DELETE", "HEAD", "OPTIONS", "TRACE", "QUERY"]>;
readonly url: String;
readonly urlParams: $Array<Tuple<readonly [String, Union<readonly [String, Redacted<String>]>]>>;
}>

Example Describing an HTTP request

import type { AiError } from "effect/ai"
const requestDetails: typeof AiError.HttpRequestDetails.Type = {
method: "POST",
url: "https://api.openai.com/v1/responses",
urlParams: [],
hash: undefined,
headers: { "Content-Type": "application/json" }
}
const result = [requestDetails.method, requestDetails.urlParams] // => ["POST", []]
Since v4.0.0

Schema for HTTP responses from an AI provider.

Signature

declare const HttpResponseDetails: Struct<{
readonly headers: $Record<String, Union<readonly [String, Redacted<String>]>>;
readonly status: Int;
}>

Example Describing an HTTP response

import type { AiError } from "effect/ai"
const responseDetails: typeof AiError.HttpResponseDetails.Type = {
status: 200,
headers: {
"Content-Type": "application/json",
"X-Request-Id": "req_abc123"
}
}
const result = [responseDetails.status, responseDetails.headers["X-Request-Id"]] // => [200, "req_abc123"]
Since v4.0.0

Schema for provider-specific metadata which can be attached to error reasons.

Details

Provider-specific metadata is namespaced by provider name. Each provider value can contain arbitrary mutable JSON metadata or null.

Signature

declare const ProviderMetadata: Schema.$Record<Schema.String, Schema.NullOr<Schema.Codec<Schema.MutableJson>>>

Example Inspecting metadata shape

const metadata = {
openai: {
errorCode: "rate_limit_exceeded",
requestId: "req_123"
},
anthropic: null
}
Array.of(metadata.openai.errorCode, metadata.anthropic) // => ["rate_limit_exceeded", null]

UsageInfo

unstable
Since v4.0.0

Schema for token usage information from AI operations.

Details

Schema for optional provider-reported token counts for prompt tokens, completion tokens, and total tokens.

Signature

declare const UsageInfo: Struct<{
readonly completionTokens: optional<Int>;
readonly promptTokens: optional<Int>;
readonly totalTokens: optional<Int>;
}>

Utilities

Since v4.0.0

Builds a description for an HTTP error returned by an AI provider.

Signature

declare function buildErrorDescription(params: {
readonly body: string | undefined;
readonly errorCode?: string | number | null;
readonly errorType?: string | null;
readonly message: string | undefined;
readonly method: string;
readonly requestId?: string | null;
readonly status: number;
readonly url: string;
}): string