diff --git a/litellm/litellm_core_utils/litellm_logging.py b/litellm/litellm_core_utils/litellm_logging.py index c73d914e6cc..7c1542a204b 100644 --- a/litellm/litellm_core_utils/litellm_logging.py +++ b/litellm/litellm_core_utils/litellm_logging.py @@ -5159,12 +5159,23 @@ class StandardLoggingPayloadSetup: # Get additional error details error_message = str(original_exception) + # For rate-limit errors (litellm.RateLimitError + the proxy-side + # ProxyRateLimitError subclass), surface the unified `category` field + # so callbacks can distinguish vendor vs. litellm rate limits without + # reaching for the raw exception object. + rate_limit_category: Optional[str] = ( + getattr(original_exception, "category", None) + if original_exception is not None + else None + ) + return StandardLoggingPayloadErrorInformation( error_code=error_status, error_class=error_class, llm_provider=_llm_provider_in_exception, traceback=traceback_info, error_message=error_message if original_exception else "", + error_rate_limit_category=rate_limit_category, ) @staticmethod diff --git a/litellm/types/utils.py b/litellm/types/utils.py index 400edcac889..832ed12236c 100644 --- a/litellm/types/utils.py +++ b/litellm/types/utils.py @@ -2697,6 +2697,16 @@ class StandardLoggingPayloadErrorInformation(TypedDict, total=False): llm_provider: Optional[str] traceback: Optional[str] error_message: Optional[str] + error_rate_limit_category: Optional[str] + """ + For 429 / rate-limit errors, the source of the rate limit. One of the + string values defined by :class:`litellm.exceptions.RateLimitErrorCategory` + (``vendor_rate_limit``, ``vendor_batch_rate_limit``, ``litellm_rate_limit``, + ``litellm_batch_rate_limit``). ``None`` for non-rate-limit exceptions. + + Surfaced here so custom callbacks / metrics consumers can switch on the + rate-limit source without reaching for the raw exception. + """ class GuardrailMode(TypedDict, total=False):