# How Open Notebook Maps AI Provider Errors to HTTP Status Codes

> Discover how Open Notebook maps AI provider errors to HTTP status codes. This guide explains the normalization and mapping process using pattern matching and FastAPI exception handlers.

- Repository: [Luis Novo/open-notebook](https://github.com/lfnovo/open-notebook)
- Tags: how-to-guide
- Published: 2026-06-27

---

**Open Notebook normalizes raw AI provider exceptions into internal error types using pattern matching in [`error_classifier.py`](https://github.com/lfnovo/open-notebook/blob/main/error_classifier.py), then maps these to standard HTTP status codes through dedicated FastAPI exception handlers.**

Open Notebook, developed by lfnovo, provides a unified interface for interacting with multiple AI providers through its graph-based execution system. The application's **error classification** system ensures that low-level provider failures—whether authentication errors from OpenAI or rate limits from Anthropic—surface as consistent, actionable HTTP responses to API consumers.

## The Error Classification Pipeline

The normalization process occurs in two stages: first, raw exceptions are classified by pattern matching in [`open_notebook/utils/error_classifier.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/utils/error_classifier.py); second, FastAPI handlers in [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py) translate the classified exceptions into HTTP responses.

### Pattern Matching in error_classifier.py

The `classify_error` function examines exception messages and class names for specific keyword patterns. This utility returns a tuple containing an **OpenNotebookError** subclass and a user-friendly message.

The classification logic identifies the following patterns:

- **Authentication failures**: Keywords like `authentication`, `401`, or `invalid api key` trigger `AuthenticationError`
- **Rate limiting**: Matches for `rate limit`, `429`, or `too many requests` produce `RateLimitError`
- **Configuration issues**: Patterns like `model not found`, `does not exist`, `no model configured`, or `please go to settings` result in `ConfigurationError`
- **Network failures**: `connecterror`, `timeout`, or `connection refused` map to `NetworkError`
- **Service errors**: Context length issues (`context length`, `token limit`, `max_tokens`), payload errors (`413`, `payload too large`), or server failures (`500`, `502`, `503`, `service unavailable`) all classify as `ExternalServiceError`

If no patterns match, the system defaults to `ExternalServiceError` with a generic "AI service error" message.

## HTTP Status Code Mapping

Each internal exception type corresponds to a specific HTTP status code through dedicated handlers registered in [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py):

| Internal Exception | HTTP Status | FastAPI Handler |
|-------------------|-------------|----------------|
| `AuthenticationError` | 401 Unauthorized | `authentication_error_handler` |
| `RateLimitError` | 429 Too Many Requests | `rate_limit_error_handler` |
| `ConfigurationError` | 422 Unprocessable Entity | `configuration_error_handler` |
| `NetworkError` | 502 Bad Gateway | `network_error_handler` |
| `ExternalServiceError` | 502 Bad Gateway | `external_service_error_handler` |
| `InvalidInputError` | 400 Bad Request | `invalid_input_error_handler` |
| `NotFoundError` | 404 Not Found | `not_found_error_handler` |
| `OpenNotebookError` (generic) | 500 Internal Server Error | `open_notebook_error_handler` |

All handlers add CORS headers to responses for consistency across browser clients.

## Implementation Examples

### Classifying Provider Exceptions

Graph nodes in `open_notebook/graphs/*.py` and API routers in `api/routers/*.py` utilize the `classify_error` utility to wrap provider calls:

```python
from open_notebook.utils.error_classifier import classify_error
from open_notebook.exceptions import AuthenticationError

try:
    result = provider.generate(prompt)
except Exception as exc:
    exc_class, user_msg = classify_error(exc)
    
    if exc_class is AuthenticationError:
        raise exc_class(user_msg)

```

### FastAPI Exception Handlers

The [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py) file registers handlers that convert exceptions to JSON responses:

```python
@app.exception_handler(AuthenticationError)
async def authentication_error_handler(request: Request, exc: AuthenticationError):
    return JSONResponse(
        status_code=401,
        content={"detail": str(exc)},
        headers=_cors_headers(request),
    )

```

## Key Files in the Error Handling System

- **[`open_notebook/utils/error_classifier.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/utils/error_classifier.py)**: Contains the `classify_error` function that maps raw exceptions to internal types based on keyword patterns.
- **[`open_notebook/exceptions.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/exceptions.py)**: Defines the `OpenNotebookError` hierarchy including `AuthenticationError`, `RateLimitError`, `ConfigurationError`, `NetworkError`, and `ExternalServiceError`.
- **[`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py)**: Registers FastAPI exception handlers that translate custom exceptions into HTTP responses with appropriate status codes.
- **`open_notebook/graphs/*.py`**: Invokes `classify_error` within graph nodes to surface user-friendly errors during AI workflows.
- **`api/routers/*.py`**: Wraps graph invocations and uses error classification to return proper API responses.

## Summary

- Open Notebook's **error classification** system converts diverse AI provider exceptions into standardized internal types using pattern matching in [`error_classifier.py`](https://github.com/lfnovo/open-notebook/blob/main/error_classifier.py).
- The `classify_error` function returns a tuple of `(exception_class, user_friendly_message)` based on keyword detection in error messages.
- **FastAPI handlers** in [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py) map each exception type to specific HTTP status codes: 401 for authentication, 429 for rate limits, 422 for configuration, and 502 for network or service failures.
- Graph workflows and API routers throughout the codebase utilize this utility to ensure consistent error responses across all AI provider integrations.

## Frequently Asked Questions

### How does Open Notebook handle authentication errors from AI providers?

When the `classify_error` utility detects keywords like `authentication`, `401`, or `invalid api key` in an exception message, it returns `AuthenticationError`. The FastAPI handler `authentication_error_handler` then converts this to an HTTP 401 Unauthorized response with CORS headers, standardizing authentication failures regardless of whether they originate from OpenAI, Anthropic, or other providers.

### What HTTP status code does Open Notebook return for rate limiting?

Open Notebook returns **HTTP 429 Too Many Requests** for rate limit errors. The `classify_error` function identifies patterns like `rate limit`, `429`, or `too many requests` and raises `RateLimitError`, which the `rate_limit_error_handler` in [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py) maps to the 429 status code.

### Why does Open Notebook use 502 Bad Gateway for multiple error types?

The application uses **502 Bad Gateway** for `NetworkError` (connection timeouts, refused connections) and `ExternalServiceError` (context length exceeded, 413 payload too large, or 5xx server errors) because these represent failures in upstream AI services rather than the Open Notebook application itself. This follows HTTP semantics where 502 indicates the server received an invalid response from an upstream source.

### Where is the error classification logic implemented in the Open Notebook codebase?

The core classification logic resides in [`open_notebook/utils/error_classifier.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/utils/error_classifier.py), specifically within the `classify_error` function. The exception class definitions are in [`open_notebook/exceptions.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/exceptions.py), and the HTTP response mapping occurs through handlers registered in [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py).