BerriAI/litellm · error · BaseLLMException

{error_message}

Error message

{error_message}

What it means

This is the realtime (websocket) error-mapping hook: get_error_class raises BaseLLMException carrying the provider's status_code, error_message and headers verbatim. Encountering it means the realtime handshake or session errored at the provider (auth, model access, quota) and the generic mapper surfaced it — the literal '{error_message}' in static analysis is just the f-string template.

Source

Thrown at litellm/llms/base_llm/realtime/transformation.py:44

        headers: dict,
        model: str,
        api_key: str | None = None,
    ) -> dict:
        pass

    @abstractmethod
    def get_complete_url(self, api_base: str | None, model: str, api_key: str | None = None) -> str:
        """
        OPTIONAL

        Get the complete url for the request

        Some providers need `model` in `api_base`
        """
        return api_base or ""

    def get_error_class(self, error_message: str, status_code: int, headers: dict | httpx.Headers) -> BaseLLMException:
        raise BaseLLMException(
            status_code=status_code,
            message=error_message,
            headers=headers,
        )

    @abstractmethod
    def transform_realtime_request(
        self,
        message: str,
        model: str,
        session_configuration_request: str | None = None,
    ) -> list[str]:
        pass

    def is_setup_message(self, msg_obj: dict) -> bool:
        return False

    def is_content_message(self, msg_obj: dict) -> bool:

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Inspect the caught BaseLLMException.status_code and message to identify the upstream cause (fix key/model accordingly).
  2. For 401/403: verify API key env vars and permissions for realtime APIs.
  3. For 404/400: confirm the model name supports realtime and the api_base points at the realtime endpoint.
  4. Override get_error_class in the provider config for typed exception mapping.

Example fix

# before
try:
    litellm.realtime(model='gpt-4o-realtime', listening=True)
except Exception:
    raise

# after
from litellm.llms.base_llm.chat.transformation import BaseLLMException
try:
    litellm.realtime(model='gpt-4o-realtime', listening=True)
except BaseLLMException as e:
    logger.error('realtime failed: %s (%s)', e.message, e.status_code)
    raise
Defensive patterns

Strategy: try-catch

Validate before calling

def validate_realtime_setup(model: str, api_key: str | None, api_base: str | None) -> None:
    if not api_key:
        raise ConfigError('realtime requires an API key')
    if 'realtime' not in model and 'audio' not in model:
        warnings.warn(f'{model} may not support realtime sessions')

Try / catch

try:
    await litellm.realtime(...)
except BaseLLMException as e:
    if e.status_code in (401, 403):
        raise AuthError('realtime auth failed') from e
    if e.status_code == 429:
        await asyncio.sleep(5)
        return await litellm.realtime(...)
    raise

Prevention

When it happens

Trigger: Opening a realtime session (litellm.realtime / WebSocket bridge) with an invalid API key (401/403), nonexistent model, insufficient quota, or a provider that rejects the upgrade request; the error handler calls get_error_class with the provider's message.

Common situations: Expired or wrong OPENAI_API_KEY for realtime; using a model without realtime capability; regional endpoint misconfiguration; proxy auth layers stripping websocket headers.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/d5f6f2f5c1600f06. Report an issue: GitHub.