01 · 异常类目录:全部 25 个类型¶
本文按语义分类列出 litellm/exceptions.py 里所有公开异常类。每条给出:
- 父类(OpenAI SDK 的哪个异常)
status_code(是否硬编码 / 是否可变)- 何时抛(典型触发条件)
message前缀(grep 用)- 特殊字段(
type/code/litellm_debug_info/headers等) - Router 默认反应(cooldown / retry,详细见 03-router-behavior.md)
📌 看不到的字段:
max_retries/num_retries几乎所有异常都有,用来在__str__末尾追加LiteLLM Retried: N times。本文不重复列举。
0. 总览表¶
flowchart LR
subgraph "openai SDK"
OAuth["openai.AuthenticationError"]
ONotFound["openai.NotFoundError"]
OBadReq["openai.BadRequestError"]
OUnproc["openai.UnprocessableEntityError"]
OTimeout["openai.APITimeoutError"]
OPerm["openai.PermissionDeniedError"]
ORate["openai.RateLimitError"]
OStatus["openai.APIStatusError"]
OInternal["openai.InternalServerError"]
OAPIErr["openai.APIError"]
OConn["openai.APIConnectionError"]
OResp["openai.APIResponseValidationError"]
OOpenAI["openai.OpenAIError"]
end
OAuth --> Auth["AuthenticationError 401"]
ONotFound --> NF["NotFoundError 404"]
OBadReq --> BadReq["BadRequestError 400"]
BadReq --> ImgFetch["ImageFetchError"]
BadReq --> CtxWin["ContextWindowExceededError"]
BadReq --> Rej["RejectedRequestError"]
BadReq --> CPV["ContentPolicyViolationError"]
BadReq --> UnsupParam["UnsupportedParamsError"]
BadReq --> UnknownProv["LiteLLMUnknownProvider"]
BadReq --> Invalid["InvalidRequestError ⚠️deprecated"]
OUnproc --> Unproc["UnprocessableEntityError 422"]
OTimeout --> TO["Timeout 408 (可改)"]
OPerm --> Perm["PermissionDeniedError 403"]
ORate --> Rate["RateLimitError 429"]
OStatus --> SU["ServiceUnavailableError 503"]
OStatus --> BGW["BadGatewayError 502"]
SU --> MidStream["MidStreamFallbackError"]
OInternal --> Internal["InternalServerError 500"]
OAPIErr --> APIErr["APIError 可变 status"]
OAPIErr --> Mock["MockException"]
OConn --> Conn["APIConnectionError ⚠️硬编码 500"]
OResp --> RespVal["APIResponseValidationError 500"]
RespVal --> JSON["JSONSchemaValidationError"]
OOpenAI --> OAIErr["OpenAIError"]
BaseExc["Python Exception"] --> Budget["BudgetExceededError"]
BaseExc --> Guard["GuardrailRaisedException"]
BaseExc --> PII["BlockedPiiEntityError"]
BaseExc --> GuardStr["GuardrailInterventionNormalStringError"]
style Conn fill:#fdd,stroke:#c33
style Invalid fill:#fdd,stroke:#c33
style MidStream fill:#ffd,stroke:#aa3
⚠️ 红框标的两个是有"陷阱"性质的:
- APIConnectionError —— status_code 跟语义不对齐(见 §3.1)
- InvalidRequestError —— 标 deprecated,仍存在于代码里
1. 用户错(不进 cooldown,不 retry)¶
这一类异常 Router 视为"调用方问题",不会冷却 deployment,不会自动 retry。客户端收到对应 status_code 就该直接处理(修 payload / 升级权限 / 减少 token)。
1.1 BadRequestError — 400¶
| 字段 | 值 |
|---|---|
| 行号 | exceptions.py:126 |
| 父类 | openai.BadRequestError |
status_code |
400(硬编码) |
| 必传参数 | message / model / llm_provider |
| 可选 | response / body / litellm_debug_info / max_retries / num_retries |
| message 前缀 | litellm.BadRequestError: |
| Router | ❌ 不 cooldown ❌ 不 retry |
何时抛:上游返回 400、或 LiteLLM 校验 payload 失败。exception_mapping_utils.py 里几乎每个 provider 都有 400 分支映射到这里。
特殊:response 参数会做 _request 字段检查(exceptions.py:147-155),避免 httpx response 没 request 时崩溃。
1.2 UnprocessableEntityError — 422¶
| 字段 | 值 |
|---|---|
| 行号 | exceptions.py:201 |
| 父类 | openai.UnprocessableEntityError |
status_code |
422 |
| message 前缀 | litellm.UnprocessableEntityError: |
| Router | ❌ 不 cooldown ❌ 不 retry |
何时抛:上游返回 422(payload 结构合法但语义不通过,如 schema 验证失败)。
1.3 PermissionDeniedError — 403¶
| 字段 | 值 |
|---|---|
| 行号 | exceptions.py:286 |
| 父类 | openai.PermissionDeniedError |
status_code |
403 |
| message 前缀 | litellm.PermissionDeniedError: |
| Router | ❌ 不 cooldown ❌ 不 retry |
何时抛:上游 403(API key 权限不够 / region 限制 / 模型未开通)。注意 401(key 错)走 AuthenticationError。
1.4 ContextWindowExceededError — 400 子类¶
| 字段 | 值 |
|---|---|
| 行号 | exceptions.py:378 |
| 父类 | BadRequestError |
status_code |
400 |
| message 前缀 | litellm.ContextWindowExceededError: |
| Router | ❌ 不 cooldown ❌ 不 retry(fallback 链可触发 context_window_fallbacks) |
何时抛:上游 400 且错误消息含"context length / token limit / max_tokens"等关键字。映射代码常见于各 provider transformation 的 handle_error 里基于 message 关键字判断。
fallback 特殊:Router 支持 context_window_fallbacks 配置——这类异常专门切到长 context 模型。但 cooldown 不触发。
1.5 ContentPolicyViolationError — 400 子类¶
| 字段 | 值 |
|---|---|
| 行号 | exceptions.py:462 |
| 父类 | BadRequestError |
status_code |
400 |
| message 前缀 | litellm.ContentPolicyViolationError: |
| 特殊字段 | provider_specific_fields / body |
| Router | ❌ 不 cooldown ❌ 不 retry(fallback 链可触发 content_policy_fallbacks 或 ContentPolicyViolationErrorRetries) |
何时抛:上游内容审核拒绝(如 OpenAI 的 code=content_policy_violation / Azure content filter / Vertex safety check)。
RetryPolicy 支持:get_retry_from_policy.py:53-57 允许配置 ContentPolicyViolationErrorRetries,但默认 0。
1.6 RejectedRequestError — 400 子类(guardrails)¶
| 字段 | 值 |
|---|---|
| 行号 | exceptions.py:420 |
| 父类 | BadRequestError |
status_code |
400 |
| 特殊字段 | request_data: dict |
| message 前缀 | litellm.RejectedRequestError: |
| Router | ❌ 不 cooldown ❌ 不 retry |
何时抛:LiteLLM proxy 的 guardrail hooks 主动拒绝请求时。保留原始 request_data 给 callback 用于审计。
1.7 UnsupportedParamsError — 400 子类¶
| 字段 | 值 |
|---|---|
| 行号 | exceptions.py:795 |
| 父类 | BadRequestError |
status_code |
400 |
| message 前缀 | litellm.UnsupportedParamsError: |
何时抛:调用方传了当前 provider 不支持的参数(如 OpenAI 专属字段传给 Anthropic)。LiteLLM 的 get_optional_params 校验环节抛出。
1.8 LiteLLMUnknownProvider — 400 子类¶
| 字段 | 值 |
|---|---|
| 行号 | exceptions.py:912 |
| 父类 | BadRequestError |
status_code |
400 |
| message 模板 | LLM Provider NOT provided. Pass in the LLM provider you are trying to call. ... |
何时抛:model 参数前缀认不出来(如写错 gpt-7)。
1.9 ImageFetchError — 400 子类¶
| 字段 | 值 |
|---|---|
| 行号 | exceptions.py:177 |
| 父类 | BadRequestError |
status_code |
400 |
何时抛:用户传的 image URL 下载失败 / 解码失败。在多模态请求里常见。
1.10 InvalidRequestError — ⚠️ deprecated¶
| 字段 | 值 |
|---|---|
| 行号 | exceptions.py:870 |
| 父类 | openai.BadRequestError(不经过 BadRequestError) |
status_code |
400 |
何时抛:标 deprecated,新代码不该再用。message 不加 litellm. 前缀。看到此类异常说明走的是历史代码路径。
2. Deployment 健康问题(进 cooldown 白名单)¶
这一类异常 Router 视为"deployment 自己的问题",会走 cooldown 流程(cooldown_handlers.py:40-95)。是否最终 cooldown 还要看 V1/V2 触发路径(详见 docs/cooldown/01-mechanism.md §3)。
2.1 AuthenticationError — 401¶
| 字段 | 值 |
|---|---|
| 行号 | exceptions.py:35 |
| 父类 | openai.AuthenticationError |
status_code |
401 |
| message 前缀 | litellm.AuthenticationError: |
| Router | ✅ 进 cooldown(路径 1.4 永久错误立即冷) ❌ 不 retry(_should_retry(401)=False) |
何时抛:上游返回 401(API key 错 / expired / 无效 token)。
RetryPolicy 支持:AuthenticationErrorRetries(get_retry_from_policy.py:47-50)。但默认行为是不重试。
⚠️ 跨 Pod 暗坑:401 立即 cooldown 该 deployment,5 秒后自动恢复。如果 key 真的换掉了,需要等到自然过期 + 下次请求实际撞它才会再次进 cooldown。
2.2 NotFoundError — 404¶
| 字段 | 值 |
|---|---|
| 行号 | exceptions.py:81 |
| 父类 | openai.NotFoundError |
status_code |
404 |
| message 前缀 | litellm.NotFoundError: |
| Router | ✅ 进 cooldown(路径 1.4) ❌ 不 retry |
何时抛:上游说模型不存在 / endpoint 不存在。多见于 model 写错或 deployment 配置漂移。
2.3 Timeout — 408(可改)¶
| 字段 | 值 |
|---|---|
| 行号 | exceptions.py:240 |
| 父类 | openai.APITimeoutError |
status_code |
408(默认)/ 由 exception_status_code 入参覆盖 |
| 特殊字段 | headers / exception_status_code |
| message 前缀 | litellm.Timeout: |
| Router | ✅ 进 cooldown ✅ 会 retry(_should_retry(408)=True) |
何时抛:LiteLLM httpx 客户端本地超时(network timeout / response time > deployment timeout 配置)。
RetryPolicy 支持:TimeoutErrorRetries(get_retry_from_policy.py:51-52)。
⚠️ 注意:上游真返 504 走的是 Timeout 还是 APIError/InternalServerError,取决于 provider transformation 怎么映射。本地 socket 超时是 408,上游 gateway timeout 504 多被映射为 Timeout(exception_status_code=504) 或 APIError(status_code=504)。
2.4 RateLimitError — 429¶
| 字段 | 值 |
|---|---|
| 行号 | exceptions.py:325 |
| 父类 | openai.RateLimitError |
status_code |
429 |
| 特殊字段 | code="429" type="throttling_error" |
| message 前缀 | litellm.RateLimitError: |
| Router | ✅ 进 cooldown(路径 1.1:429 + 多 deployment 立即冷) ✅ 会 retry |
何时抛:上游限流 / LiteLLM 用户 rate-limit 命中 / Router pre-call rate-limit 检查命中。
RetryPolicy 支持:RateLimitErrorRetries(get_retry_from_policy.py:53-57)。
特殊:保留 response.headers(用于 Retry-After 头)→ Router 算 time_to_cooldown 时会读这个头(router.py:5767-5772)。
2.5 InternalServerError — 500¶
| 字段 | 值 |
|---|---|
| 行号 | exceptions.py:607 |
| 父类 | openai.InternalServerError |
status_code |
500 |
| message 前缀 | litellm.InternalServerError: |
| Router | ✅ 进 cooldown ✅ 会 retry |
何时抛:上游 5xx 中真正的 500("上游自己的代码崩了")。
2.6 ServiceUnavailableError — 503¶
| 字段 | 值 |
|---|---|
| 行号 | exceptions.py:507 |
| 父类 | openai.APIStatusError |
status_code |
503 |
| message 前缀 | litellm.ServiceUnavailableError: |
| Router | ✅ 进 cooldown ✅ 会 retry |
何时抛:上游 503(服务暂时不可用 / 后端容量不足)。常见于 cohere / bedrock / vertex。
2.7 BadGatewayError — 502¶
| 字段 | 值 |
|---|---|
| 行号 | exceptions.py:557 |
| 父类 | openai.APIStatusError |
status_code |
502 |
| message 前缀 | litellm.BadGatewayError: |
| Router | ✅ 进 cooldown ✅ 会 retry |
何时抛:上游 502(网关挂了 / 上游的上游不通)。
⚠️ 历史 bug:vertex_ai 分支曾把 502 错误映射到 APIConnectionError,导致 Router 不冷却(详见 02-provider-mapping.md §4 已知不一致)。2026-05-29 commit 2bee019 修复。
2.8 MidStreamFallbackError — 503 子类¶
| 字段 | 值 |
|---|---|
| 行号 | exceptions.py:953 |
| 父类 | ServiceUnavailableError |
status_code |
503 |
| 特殊字段 | original_exception / generated_content / is_pre_first_chunk |
| message 前缀 | litellm.MidStreamFallbackError: |
| Router | ✅ 进 cooldown ✅ 会 retry(按 503 处理) |
何时抛:流式响应在传输中断、需要中途切到 fallback 时。保留已生成的 partial content(generated_content)和原始异常(original_exception),供 fallback 链上的下一个 deployment 复用。
is_pre_first_chunk 区分是不是"还没开始流就挂了"——这影响 fallback 能否丢弃 generated_content。
3. LiteLLM 自身 / 协议层(特殊语义)¶
3.1 APIConnectionError — ⚠️ 硬编码 500,被 cooldown 跳过¶
| 字段 | 值 |
|---|---|
| 行号 | exceptions.py:699 |
| 父类 | openai.APIConnectionError |
status_code |
500(硬编码) ← 不是上游真实状态 |
| message 前缀 | litellm.APIConnectionError: |
| Router | ❌ 被字符串白名单跳过(cooldown_handlers.py:57-63) ❌ 不 retry |
何时抛: - LiteLLM httpx 客户端连接失败(DNS / TCP / SSL 握手) - 各 provider transformation 里"no status code"兜底分支(exception_mapping_utils.py:606-609 等) - 一部分 provider 的 502/503 兜底(如 vllm exception_mapping_utils.py:2047)
⚠️ 三个坑:
- status_code 不是 HTTP 实际状态:exceptions.py:713
self.status_code = 500硬编码。message 里写"上游 502"但 status_code 报 500,监控就会错位。 - Router 不冷却:cooldown_handlers 的
ignored_strings = ["APIConnectionError"]看 message 字符串放行。如果上游真挂被误映射到这个类,Router 会反复打坏实例。 - 不被
_should_retry:utils.py:6526 看status_code决定。status_code=500 满足 ≥500,应该 retry——但因为 cooldown 跳过 + 异常没 raised httpx response,Router 实际处理路径可能跟纯 5xx 不一样。
判断"该不该用这个类": - ✅ 该用:本机 DNS 解析失败、TCP 拒绝连接、SSL 错、socket 断 - ❌ 不该用:上游返回了 502/503/504 但状态码确定
3.2 APIError — 可变 status_code¶
| 字段 | 值 |
|---|---|
| 行号 | exceptions.py:658 |
| 父类 | openai.APIError |
status_code |
入参传入(任何整数) |
| 必传参数 | status_code / message / llm_provider / model |
| message 前缀 | litellm.APIError: |
| Router | 取决于 status_code |
何时抛:兜底 / 没法分类的上游错误。各 provider 的"其它 status_code"分支常用这个,常见 504 / 524 / 524 / 528 等冷门状态。
用法判断:抛 APIError 时必须手动传 status_code——这是它跟其他异常的核心差别。Router 行为由传入的 status_code 决定。
3.3 APIResponseValidationError — 500¶
| 字段 | 值 |
|---|---|
| 行号 | exceptions.py:738 |
| 父类 | openai.APIResponseValidationError |
status_code |
500(隐式,response 里设的) |
| message 前缀 | litellm.APIResponseValidationError: |
何时抛:上游 HTTP 200 但响应体不符合预期 schema(如 OpenAI 兼容接口返回了 LiteLLM 无法解析的格式)。
3.4 JSONSchemaValidationError — APIResponseValidationError 子类¶
| 字段 | 值 |
|---|---|
| 行号 | exceptions.py:775 |
| 父类 | APIResponseValidationError |
| 特殊字段 | raw_response / schema |
| message 模板 | litellm.JSONSchemaValidationError: model={}, returned an invalid response={}, for schema={}... |
何时抛:用户传了 response_format 要求 structured output,但上游返回的 JSON 不符合给定的 schema。e.raw_response 保存原始响应供排查。
3.5 OpenAIError¶
| 字段 | 值 |
|---|---|
| 行号 | exceptions.py:789 |
| 父类 | openai.OpenAIError |
status_code |
无 |
llm_provider |
固定 "openai" |
何时抛:OpenAI SDK 抛出的非状态码错(如 client 初始化错)。LiteLLM 一般不主动抛。
4. Guardrail / 内容审核 / Budget(非 OpenAI 系)¶
这一类直接继承 Exception,不是 OpenAI 兼容异常。会被 proxy 层 ProxyException 包装成特定 status_code 给客户端。
4.1 BudgetExceededError¶
| 字段 | 值 |
|---|---|
| 行号 | exceptions.py:846 |
| 父类 | Exception |
| 特殊字段 | current_cost / max_budget / user_email / team_alias / team_id |
| message 模板 | Budget has been exceeded! Current cost: X, Max budget: Y |
何时抛:proxy 层 auth check 发现 key/team/user 超预算。被包成 400 或 429 返回客户端(取决于 proxy 层处理)。
4.2 GuardrailRaisedException¶
| 字段 | 值 |
|---|---|
| 行号 | exceptions.py:925 |
| 父类 | Exception |
| 特殊字段 | guardrail_name / should_wrap_with_default_message |
| message 模板 | Guardrail raised an exception, Guardrail: {name}, Message: {msg} |
何时抛:guardrail hook 主动拒绝。一般被 proxy 层捕获后转 RejectedRequestError。
4.3 BlockedPiiEntityError¶
| 字段 | 值 |
|---|---|
| 行号 | exceptions.py:938 |
| 父类 | Exception |
| 特殊字段 | entity_type / guardrail_name |
| message 模板 | Blocked entity detected: {type} by Guardrail: {name}. ... |
何时抛:PII guardrail 在 input 里发现了禁止的实体类型(如 SSN / credit_card / phone)。
4.4 GuardrailInterventionNormalStringError¶
| 字段 | 值 |
|---|---|
| 行号 | exceptions.py:1015 |
| 父类 | Exception |
何时抛:特殊路径——guardrail 拦截但希望给用户返回一个正常字符串响应(而非 HTTP 错误)。proxy 层用它把 LLM 的"违规内容"替换为静态提示文本。
5. 测试专用¶
5.1 MockException — 任意 status_code¶
| 字段 | 值 |
|---|---|
| 行号 | exceptions.py:887 |
| 父类 | openai.APIError |
status_code |
入参传入 |
| message 前缀 | litellm.MockException: |
何时抛:单元测试模拟特定状态码的异常。不应在生产代码出现。
6. LITELLM_EXCEPTION_TYPES 白名单¶
exceptions.py:822-843 定义了一个白名单数组:
LITELLM_EXCEPTION_TYPES = [
AuthenticationError, NotFoundError, BadRequestError,
UnprocessableEntityError, UnsupportedParamsError,
Timeout, PermissionDeniedError, RateLimitError,
ContextWindowExceededError, RejectedRequestError,
ContentPolicyViolationError,
InternalServerError, ServiceUnavailableError, BadGatewayError,
APIError, APIConnectionError,
APIResponseValidationError, OpenAIError,
InternalServerError, # 重复(笔误?)
JSONSchemaValidationError,
]
用途:exception_mapping_utils.py:240-244 用它做"已经是 LiteLLM 异常就直接 return"的判定,避免二次包装。
漏掉的类:
- MidStreamFallbackError 没列(但它是 ServiceUnavailableError 子类,isinstance 检查能命中)
- ImageFetchError / ContentPolicyViolationError 等 BadRequestError 子类同理
- Guardrail / Budget 系列不在白名单内——它们本来就不走 exception_type() 二次包装
潜在 bug:InternalServerError 在数组里出现了两次(行 834、841)。功能上无副作用(Python list 允许重复,isinstance 不区分),但是是个该清理的笔误。
7. status_code 速查表¶
按 status_code 分组(含子类):
| status | 异常类(按可能性排序) | 进 cooldown | retry |
|---|---|---|---|
| 400 | BadRequestError / ContextWindowExceededError / ContentPolicyViolationError / RejectedRequestError / UnsupportedParamsError / LiteLLMUnknownProvider / ImageFetchError / InvalidRequestError(dep) |
❌ | ❌ |
| 401 | AuthenticationError |
✅ 路径 1.4 | ❌ |
| 403 | PermissionDeniedError |
❌ | ❌ |
| 404 | NotFoundError |
✅ 路径 1.4 | ❌ |
| 408 | Timeout(默认) |
✅ | ✅ |
| 422 | UnprocessableEntityError |
❌ | ❌ |
| 429 | RateLimitError |
✅ 路径 1.1(多 deployment 即冷) | ✅ |
| 500 | InternalServerError / APIConnectionError(⚠️) / APIResponseValidationError / JSONSchemaValidationError |
✅ / ❌(被字符串白名单跳过) / ❌ / ❌ | ✅ / ❌ / ❌ / ❌ |
| 502 | BadGatewayError |
✅ | ✅ |
| 503 | ServiceUnavailableError / MidStreamFallbackError |
✅ | ✅ |
| 可变 | APIError / MockException / Timeout(可改) |
取决于实际值 | 取决于实际值 |
| 无 | OpenAIError / BudgetExceededError / GuardrailRaisedException / BlockedPiiEntityError / GuardrailInterventionNormalStringError |
N/A(不走 Router 失败回调) | N/A |
下一步¶
- 各 provider 抛哪些类、跨 provider 不一致 → 02-provider-mapping.md
- 每个异常详细 Router 行为(cooldown 路径 / retry 次数 / fallback 触发) → 03-router-behavior.md
- 客户端看到什么 / 日志关键词 → 04-where-to-see.md
- 从症状倒推根因 → 05-troubleshooting-by-symptom.md