> ## Documentation Index
> Fetch the complete documentation index at: https://docs.core-ai.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors

> Error classes for handling core-ai and provider failures

## Overview

core-ai provides a hierarchy of error classes for handling different types of failures when working with language models. All errors extend from `CoreAIError` and provide structured error information.

## Error Hierarchy

```
CoreAIError
├── ValidationError
├── AbortedError
│   └── StreamAbortedError
├── ProviderError
└── StructuredOutputError
    ├── StructuredOutputNoObjectGeneratedError
    ├── StructuredOutputParseError
    └── StructuredOutputValidationError
```

## CoreAIError

Base error class for all core-ai errors.

```typescript theme={null}
export class CoreAIError extends Error {
    public readonly provider?: string;
    public readonly cause?: unknown;

    constructor(message: string, cause?: unknown, provider?: string) {
        super(message);
        this.name = 'CoreAIError';
        this.cause = cause;
        this.provider = provider;
    }
}
```

## ValidationError

Thrown when core-ai rejects invalid caller input or local request configuration before calling a provider.

```typescript theme={null}
export class ValidationError extends CoreAIError {
    constructor(message: string, cause?: unknown, provider?: string) {
        super(message, cause, provider);
        this.name = 'ValidationError';
    }
}
```

### Properties

<ParamField path="message" type="string">
  Error message describing what went wrong.
</ParamField>

<ParamField path="cause" type="unknown">
  Optional underlying cause of the error (e.g., network error, API error).
</ParamField>

<ParamField path="provider" type="string | undefined">
  Optional provider context when the error can be attributed to a provider.
</ParamField>

<ParamField path="name" type="string">
  Error name, always `'CoreAIError'`.
</ParamField>

### Example

```typescript theme={null}
import { CoreAIError } from '@core-ai/core-ai';

try {
  // Some operation
  throw new CoreAIError('Something went wrong');
} catch (error) {
  if (error instanceof CoreAIError) {
    console.error('CoreAIError:', error.message);
    if (error.cause) {
      console.error('Caused by:', error.cause);
    }
  }
}
```

## AbortedError

Thrown when an operation is cancelled via an `AbortSignal`.

```typescript theme={null}
export class AbortedError extends CoreAIError {
    constructor(cause?: unknown, provider?: string) {
        super('operation aborted', cause, provider);
        this.name = 'AbortedError';
    }
}
```

## StreamAbortedError

Thrown when a streaming operation is aborted via an `AbortSignal`.

```typescript theme={null}
export class StreamAbortedError extends AbortedError {
    constructor(cause?: unknown, provider?: string) {
        super(cause, provider);
        this.name = 'StreamAbortedError';
        this.message = 'stream aborted';
    }
}
```

### Example

```typescript theme={null}
import { stream } from '@core-ai/core-ai';
import { StreamAbortedError } from '@core-ai/core-ai';

const controller = new AbortController();
setTimeout(() => controller.abort(), 5000);

try {
  const chatStream = await stream({
    model,
    messages: [{ role: 'user', content: 'Write a long story' }],
    signal: controller.signal,
  });

  for await (const event of chatStream) {
    if (event.type === 'text-delta') {
      process.stdout.write(event.text);
    }
  }
} catch (error) {
  if (error instanceof StreamAbortedError) {
    console.log('Stream was cancelled');
  }
}
```

## ProviderError

Error specific to provider/API failures.

```typescript theme={null}
export class ProviderError extends CoreAIError {
    public readonly statusCode?: number;

    constructor(
        message: string,
        provider: string,
        statusCode?: number,
        cause?: unknown
    ) {
        super(message, cause, provider);
        this.name = 'ProviderError';
        this.statusCode = statusCode;
    }
}
```

### Properties

<ParamField path="provider" type="string">
  The provider that threw the error (e.g., `'openai'`, `'anthropic'`).
</ParamField>

<ParamField path="statusCode" type="number | undefined">
  HTTP status code if available (e.g., `404`, `500`, `429`).
</ParamField>

### Example

```typescript theme={null}
import { generate, ProviderError } from '@core-ai/core-ai';
import { createOpenAI } from '@core-ai/openai';

const openai = createOpenAI();
const model = openai.chatModel('gpt-5-mini');

try {
  const result = await generate({
    model,
    messages: [{ role: 'user', content: 'Hello' }]
  });
} catch (error) {
  if (error instanceof ProviderError) {
    console.error(`Provider ${error.provider} error:`, error.message);
    
    if (error.statusCode === 429) {
      console.error('Rate limit exceeded');
    } else if (error.statusCode === 401) {
      console.error('Authentication failed');
    } else if (error.statusCode && error.statusCode >= 500) {
      console.error('Provider server error');
    }
  }
}
```

## StructuredOutputError

Base class for errors related to structured output generation (objects).

```typescript theme={null}
export class StructuredOutputError extends CoreAIError {
    public readonly statusCode?: number;
    public readonly rawOutput?: string;

    constructor(
        message: string,
        provider: string,
        options: StructuredOutputErrorOptions = {}
    ) {
        super(message, options.cause, provider);
        this.name = 'StructuredOutputError';
        this.statusCode = options.statusCode;
        this.rawOutput = options.rawOutput;
    }
}

type StructuredOutputErrorOptions = {
    statusCode?: number;
    cause?: unknown;
    rawOutput?: string;
};
```

### Properties

<ParamField path="rawOutput" type="string | undefined">
  The raw output from the model that failed to parse/validate.
</ParamField>

### Example

```typescript theme={null}
import { StructuredOutputError } from '@core-ai/core-ai';

try {
  const result = await generateObject({
    model,
    messages: [{ role: 'user', content: 'Generate data' }],
    schema: z.object({ name: z.string() })
  });
} catch (error) {
  if (error instanceof StructuredOutputError) {
    console.error('Structured output error:', error.message);
    console.error('Provider:', error.provider);
    
    if (error.rawOutput) {
      console.error('Raw output:', error.rawOutput);
    }
  }
}
```

## StructuredOutputNoObjectGeneratedError

Thrown when the model doesn't generate an object at all.

```typescript theme={null}
export class StructuredOutputNoObjectGeneratedError extends StructuredOutputError {
    constructor(
        message: string,
        provider: string,
        options: StructuredOutputErrorOptions = {}
    ) {
        super(message, provider, options);
        this.name = 'StructuredOutputNoObjectGeneratedError';
    }
}
```

### Example

```typescript theme={null}
import { StructuredOutputNoObjectGeneratedError } from '@core-ai/core-ai';

try {
  const result = await generateObject({
    model,
    messages: [{ role: 'user', content: 'Hello' }],
    schema: z.object({ name: z.string() })
  });
} catch (error) {
  if (error instanceof StructuredOutputNoObjectGeneratedError) {
    console.error('Model did not generate an object');
    console.error('Provider:', error.provider);
  }
}
```

## StructuredOutputParseError

Thrown when the model's output cannot be parsed as JSON.

```typescript theme={null}
export class StructuredOutputParseError extends StructuredOutputError {
    constructor(
        message: string,
        provider: string,
        options: StructuredOutputErrorOptions = {}
    ) {
        super(message, provider, options);
        this.name = 'StructuredOutputParseError';
    }
}
```

### Example

```typescript theme={null}
import { StructuredOutputParseError } from '@core-ai/core-ai';

try {
  const result = await generateObject({
    model,
    messages: [{ role: 'user', content: 'Generate user' }],
    schema: z.object({ name: z.string() })
  });
} catch (error) {
  if (error instanceof StructuredOutputParseError) {
    console.error('Failed to parse model output as JSON');
    console.error('Raw output:', error.rawOutput);
    console.error('Parse error:', error.cause);
  }
}
```

## StructuredOutputValidationError

Thrown when the model's output doesn't match the Zod schema.

```typescript theme={null}
export class StructuredOutputValidationError extends StructuredOutputError {
    public readonly issues: string[];

    constructor(
        message: string,
        provider: string,
        issues: string[],
        options: StructuredOutputErrorOptions = {}
    ) {
        super(message, provider, options);
        this.name = 'StructuredOutputValidationError';
        this.issues = issues;
    }
}
```

### Properties

<ParamField path="issues" type="string[]">
  Array of validation error messages from Zod.
</ParamField>

### Example

```typescript theme={null}
import { StructuredOutputValidationError } from '@core-ai/core-ai';
import { z } from 'zod';

try {
  const result = await generateObject({
    model,
    messages: [{ role: 'user', content: 'Generate user' }],
    schema: z.object({
      name: z.string(),
      age: z.number().min(0).max(120),
      email: z.string().email()
    })
  });
} catch (error) {
  if (error instanceof StructuredOutputValidationError) {
    console.error('Schema validation failed');
    console.error('Issues:');
    error.issues.forEach(issue => {
      console.error(`  - ${issue}`);
    });
    console.error('Raw output:', error.rawOutput);
  }
}
```

## Error Handling Patterns

### Comprehensive Error Handling

```typescript theme={null}
import {
  CoreAIError,
  ProviderError,
  StructuredOutputError,
  StructuredOutputNoObjectGeneratedError,
  StructuredOutputParseError,
  StructuredOutputValidationError
} from '@core-ai/core-ai';

try {
  const result = await generateObject({
    model,
    messages: [{ role: 'user', content: 'Generate data' }],
    schema: z.object({ name: z.string() })
  });
} catch (error) {
  // Handle specific errors first
  if (error instanceof StructuredOutputValidationError) {
    console.error('Validation failed:');
    error.issues.forEach(issue => console.error(issue));
    return handleValidationError(error);
  }
  
  if (error instanceof StructuredOutputParseError) {
    console.error('Parse error:', error.rawOutput);
    return handleParseError(error);
  }
  
  if (error instanceof StructuredOutputNoObjectGeneratedError) {
    console.error('No object generated');
    return handleNoObjectError(error);
  }
  
  // Handle provider errors
  if (error instanceof ProviderError) {
    if (error.statusCode === 429) {
      return handleRateLimit(error);
    }
    if (error.statusCode && error.statusCode >= 500) {
      return handleServerError(error);
    }
    return handleProviderError(error);
  }
  
  // Handle general core-ai errors
  if (error instanceof CoreAIError) {
    console.error('core-ai error:', error.message);
    return handleCoreAIError(error);
  }
  
  // Unknown error
  throw error;
}
```

### Retry Logic with Error Handling

```typescript theme={null}
async function generateWithRetry<T>(
  fn: () => Promise<T>,
  maxRetries = 3
): Promise<T> {
  let lastError: Error;
  
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await fn();
    } catch (error) {
      lastError = error as Error;
      
      if (error instanceof ProviderError) {
        // Don't retry client errors (4xx)
        if (error.statusCode && error.statusCode >= 400 && error.statusCode < 500) {
          throw error;
        }
        
        // Retry server errors (5xx) and rate limits
        if (error.statusCode === 429 || (error.statusCode && error.statusCode >= 500)) {
          const delay = Math.pow(2, i) * 1000; // Exponential backoff
          console.log(`Retrying in ${delay}ms...`);
          await new Promise(resolve => setTimeout(resolve, delay));
          continue;
        }
      }
      
      // Don't retry validation errors
      if (error instanceof StructuredOutputValidationError) {
        throw error;
      }
      
      // Retry other errors
      if (i < maxRetries - 1) {
        console.log(`Attempt ${i + 1} failed, retrying...`);
      }
    }
  }
  
  throw lastError!;
}

// Usage
const result = await generateWithRetry(() => 
  generate({
    model,
    messages: [{ role: 'user', content: 'Hello' }]
  })
);
```

### Logging and Monitoring

```typescript theme={null}
function logError(error: unknown): void {
  if (error instanceof StructuredOutputValidationError) {
    console.error({
      type: 'validation_error',
      provider: error.provider,
      issues: error.issues,
      rawOutput: error.rawOutput
    });
  } else if (error instanceof StructuredOutputParseError) {
    console.error({
      type: 'parse_error',
      provider: error.provider,
      rawOutput: error.rawOutput
    });
  } else if (error instanceof ProviderError) {
    console.error({
      type: 'provider_error',
      provider: error.provider,
      statusCode: error.statusCode,
      message: error.message
    });
  } else if (error instanceof CoreAIError) {
    console.error({
      type: 'core_ai_error',
      message: error.message,
      cause: error.cause
    });
  }
}
```

### Graceful Degradation

```typescript theme={null}
async function generateWithFallback(
  primaryModel: ChatModel,
  fallbackModel: ChatModel,
  messages: Message[]
): Promise<GenerateResult> {
  try {
    return await generate({
      model: primaryModel,
      messages
    });
  } catch (error) {
    if (error instanceof ProviderError) {
      console.warn('Primary model failed, using fallback');
      
      try {
        return await generate({
          model: fallbackModel,
          messages
        });
      } catch (fallbackError) {
        console.error('Fallback also failed');
        throw fallbackError;
      }
    }
    
    throw error;
  }
}
```

## Best Practices

<Tip>
  Always check for specific error types before general ones. Use `instanceof` checks in order from most specific to least specific.
</Tip>

<Warning>
  Don't retry validation errors (`StructuredOutputValidationError`) - they indicate a schema mismatch that won't be fixed by retrying.
</Warning>

<Tip>
  Use exponential backoff for retrying rate limit errors (429) and server errors (5xx).
</Tip>

<Info>
  The `rawOutput` property in structured output errors is useful for debugging what the model actually generated.
</Info>

<Tip>
  Log error details including provider, status codes, and causes for debugging and monitoring.
</Tip>

## Common HTTP Status Codes

* `400` - Bad Request (invalid parameters)
* `401` - Unauthorized (invalid API key)
* `403` - Forbidden (insufficient permissions)
* `404` - Not Found (invalid model or endpoint)
* `429` - Too Many Requests (rate limit exceeded)
* `500` - Internal Server Error
* `502` - Bad Gateway
* `503` - Service Unavailable
