Skip to main content
The SDK normalizes common provider errors into typed, provider‑agnostic exceptions so your application can handle them consistently across OpenAI, Anthropic, Groq, Google, and others. This guide explains when these errors occur and shows recommended handling patterns for both direct LLM usage and higher‑level agent/conversation flows.

Why typed exceptions?

LLM providers format errors differently (status codes, messages, exception classes). The SDK maps those into stable types so client apps don’t depend on provider‑specific details. Typical benefits:
  • One code path to handle auth, rate limits, timeouts, service issues, and bad requests
  • Clear behavior when conversation history exceeds the context window
  • Backward compatibility when you switch providers or SDK versions

Quick start: Using agents and conversations

Agent-driven conversations are the common entry point. Exceptions from the underlying LLM calls bubble up from conversation.run() and conversation.send_message(...) when a condenser is not configured.

Avoiding context‑window errors with a condenser

If a condenser is configured, the SDK emits a condensation request event instead of raising LLMContextWindowExceedError. The agent will summarize older history and continue.
See the dedicated guide: Context Condenser.

Handling errors with direct LLM calls

The same exceptions are raised from both LLM.completion() and LLM.responses() paths, so you can share handlers.

Example: Using .completion()

Example: Using .responses()

Rate Limits, Quota, and Budget Denials

LLMRateLimitError can represent a temporary rate limit or an exhausted allowance. Use is_quota_exhaustion_error() to distinguish them instead of parsing the error message in your application:
Temporary rate limits use the configured SDK retry policy. Recognized hard quota errors, such as insufficient_quota and usage_limit_reached, skip retries and can use a configured fallback model. Explicit budget_exceeded denials stop both retries and fallback. A fallback model still uses its own retry policy for temporary failures. Profile pre-flight validation follows the same distinction: an exhausted quota or budget returns valid: false, while a temporary 429 returns valid: true.
Structured provider code and type fields are recognized even when the human-readable message omits the machine code. This handling is part of the unreleased structured quota fix. Earlier releases can treat these responses as temporary rate limits.

Exception reference

All exceptions live under openhands.sdk.llm.exceptions unless noted.
All of the above (except the explicit cancellation types) inherit from LLMError, so you can implement a catch‑all for unexpected SDK LLM errors while still keeping fine‑grained handlers for the most common cases.