BerriAI/litellm · error · LassoGuardrailAPIError

Lasso API rate limit exceeded

Error message

Lasso API rate limit exceeded

What it means

Raised as LassoGuardrailAPIError when the Lasso API responds with HTTP 429: your organization has exceeded its Lasso rate limit. The guardrail cannot evaluate the request, so litellm fails the call instead of skipping moderation.

Solutions

  1. Retry with exponential backoff and jitter, honoring the Retry-After header if Lasso sends one.
  2. Reduce guardrail evaluation pressure: narrow the guardrail to the hooks/modes you actually need (e.g. only pre_call) and avoid guarding low-risk traffic.
  3. Check your Lasso plan's rate limits and request a limit increase if sustained traffic legitimately exceeds them.
  4. Distribute traffic across multiple Lasso keys/workspaces if your plan supports it.

Example fix

# before
resp = await client.post(lasso_url, headers=headers, json=payload)

# after — honor 429 with backoff (tenacity)
from tenacity import retry, stop_after_attempt, wait_exponential_jitter

@retry(stop=stop_after_attempt(5), wait=wait_exponential_jitter(1, 30),
       retry=retry_if_exception=lambda e: getattr(e, "response", None) is not None and e.response.status_code == 429)
async def call_lasso():
    return await client.post(lasso_url, headers=headers, json=payload)
Defensive patterns

Strategy: retry

Type guard

from litellm.proxy.guardrails.guardrail_hooks.lasso.lasso import LassoGuardrailAPIError

def is_lasso_rate_limit(err: Exception) -> bool:
    """True when the wrapped error is a 429 from Lasso — safe to back off and retry."""
    return isinstance(err, LassoGuardrailAPIError) and "rate limit" in str(err).lower()

Try / catch

import asyncio
from litellm.proxy.guardrails.guardrail_hooks.lasso.lasso import LassoGuardrailAPIError

async def call_with_backoff(hook, data, attempts: int = 5):
    for i in range(attempts):
        try:
            return await hook(data)
        except LassoGuardrailAPIError as e:
            if "rate limit" not in str(e).lower() or i == attempts - 1:
                raise
            await asyncio.sleep(min(2 ** i + 1, 30))  # exponential backoff + jitter

Prevention

When it happens

Trigger: A guardrail hook sends a request to the Lasso API and the response status is 429 (httpx raises HTTPStatusError with response.status_code == 429), which _handle_api_error re-raises as 'Lasso API rate limit exceeded'.

Common situations: High RPS through the proxy with every call guarded; burst traffic (batch jobs, load tests); a Lasso plan with lower limits than production traffic; multiple litellm instances or environments sharing one Lasso key.

Related errors


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/0cdebef7a8c6dfa2. Report an issue: GitHub.

Appendix: source

Thrown at litellm/proxy/guardrails/guardrail_hooks/lasso/lasso.py:616

        verbose_proxy_logger.error(
            "Error calling Lasso API: %s",
            error,
            extra={
                "guardrail_name": getattr(self, "guardrail_name", "unknown"),
                "message_type": message_type,
                "error_type": type(error).__name__,
            },
        )

        # Handle specific error types if httpx is available
        if HTTPX_AVAILABLE:
            if isinstance(error, httpx.TimeoutException):
                raise LassoGuardrailAPIError("Lasso API timeout")
            elif isinstance(error, httpx.HTTPStatusError):
                if error.response.status_code == 401:
                    raise LassoGuardrailMissingSecrets("Invalid API key")
                elif error.response.status_code == 429:
                    raise LassoGuardrailAPIError("Lasso API rate limit exceeded")
                else:
                    raise LassoGuardrailAPIError(f"API error: {error.response.status_code}")

        # Generic error handling
        raise LassoGuardrailAPIError(f"Failed to verify request safety with Lasso API: {error}")

    def _log_masking_applied(
        self,
        message_type: Literal["PROMPT", "COMPLETION"],
        response: dict[str, Any],
    ) -> None:
        """Log masking application with structured context."""
        conversation_id: Final = getattr(self, "conversation_id", "unknown")
        verbose_proxy_logger.debug(
            "Lasso masking applied",
            extra={
                "guardrail_name": getattr(self, "guardrail_name", "unknown"),
                "message_type": message_type,

View on GitHub (pinned to 77b7c6c40c)