{"record":{"id":"bd226af635168be9","repo":"BerriAI/litellm","slug":"lasso-api-timeout","errorCode":null,"errorMessage":"Lasso API timeout","messagePattern":"Lasso API timeout","errorType":"exception","errorClass":"LassoGuardrailAPIError","httpStatus":null,"severity":"error","filePath":"litellm/proxy/guardrails/guardrail_hooks/lasso/lasso.py","lineNumber":611,"sourceCode":"        \"\"\"Handle API errors with specific error types.\"\"\"\n        if isinstance(error, HTTPException):\n            raise error\n\n        # Log error with context\n        verbose_proxy_logger.error(\n            \"Error calling Lasso API: %s\",\n            error,\n            extra={\n                \"guardrail_name\": getattr(self, \"guardrail_name\", \"unknown\"),\n                \"message_type\": message_type,\n                \"error_type\": type(error).__name__,\n            },\n        )\n\n        # Handle specific error types if httpx is available\n        if HTTPX_AVAILABLE:\n            if isinstance(error, httpx.TimeoutException):\n                raise LassoGuardrailAPIError(\"Lasso API timeout\")\n            elif isinstance(error, httpx.HTTPStatusError):\n                if error.response.status_code == 401:\n                    raise LassoGuardrailMissingSecrets(\"Invalid API key\")\n                elif error.response.status_code == 429:\n                    raise LassoGuardrailAPIError(\"Lasso API rate limit exceeded\")\n                else:\n                    raise LassoGuardrailAPIError(f\"API error: {error.response.status_code}\")\n\n        # Generic error handling\n        raise LassoGuardrailAPIError(f\"Failed to verify request safety with Lasso API: {error}\")\n\n    def _log_masking_applied(\n        self,\n        message_type: Literal[\"PROMPT\", \"COMPLETION\"],\n        response: dict[str, Any],\n    ) -> None:\n        \"\"\"Log masking application with structured context.\"\"\"\n        conversation_id: Final = getattr(self, \"conversation_id\", \"unknown\")","sourceCodeStart":593,"sourceCodeEnd":629,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/guardrails/guardrail_hooks/lasso/lasso.py#L593-L629","documentation":"Raised as LassoGuardrailAPIError by LassoGuardrail._handle_api_error when the outbound httpx call to the Lasso Security API raises a httpx.TimeoutException. It means the guardrail could not verify or mask the request within the HTTP client timeout, so the proxied call fails instead of letting unverified content through. The original error was already logged with guardrail_name, message_type, and error_type before this re-raise.","triggerScenarios":"Any Lasso guardrail hook (pre_call, during_call, post_call) POSTs the prompt/completion to the Lasso API; the connect/read/write/pool phase exceeds the httpx client timeout, httpx raises TimeoutException, and _handle_api_error converts it to LassoGuardrailAPIError('Lasso API timeout').","commonSituations":"Large prompts that take Lasso longer to scan than the configured timeout; network latency or an egress firewall between the proxy host and the Lasso endpoint; a Lasso-side slowdown or partial outage; deployments running with the default httpx timeout under high load.","solutions":["Retry the request with exponential backoff — transient Lasso latency is the most common cause of a timeout.","Increase the httpx timeout used by the Lasso guardrail's client (e.g. httpx.Timeout(connect=5, read=30, write=10, pool=5)) so Lasso has time to scan large payloads.","Verify egress from the proxy host/container to the Lasso API endpoint (e.g. curl -m 30 against the lasso api_base) and fix firewall, DNS, or proxy issues.","Reduce prompt size or traffic bursts through the guardrail; if timeouts persist across all requests, check Lasso status pages and your organization's quota."],"exampleFix":"# before\nclient = httpx.AsyncClient()  # default ~5s timeout; Lasso scan of a big prompt times out\n\n# after\nclient = httpx.AsyncClient(\n    timeout=httpx.Timeout(connect=5.0, read=30.0, write=10.0, pool=5.0)\n)","handlingStrategy":"retry","validationCode":"# Preflight: verify the Lasso endpoint answers within budget before serving traffic\nimport httpx, os\n\ndef lasso_reachable(timeout: float = 10.0) -> bool:\n    base = os.environ.get(\"LASSO_API_BASE\", \"https://api.lasso.security\")\n    try:\n        r = httpx.get(f\"{base}/health\", timeout=timeout)  # any lightweight route\n        return r.status_code < 500\n    except httpx.TimeoutException:\n        return False\n    except httpx.HTTPError:\n        return False","typeGuard":null,"tryCatchPattern":"from litellm.proxy.guardrails.guardrail_hooks.lasso.lasso import LassoGuardrailAPIError\n\ntry:\n    result = await guardrail_hook(data)\nexcept LassoGuardrailAPIError as e:\n    if \"timeout\" in str(e).lower():\n        # transient: back off and retry once or twice, then fail\n        await asyncio.sleep(2)\n        result = await guardrail_hook(data)\n    else:\n        raise","preventionTips":["Configure a generous read timeout (30s+) on the guardrail's httpx client — moderation scans scale with prompt size.","Alert on guardrail latency p99 so you widen timeouts before users see failures.","Keep prompts bounded; chunk very large inputs so a single scan cannot blow the timeout.","Run the lasso_reachable() preflight in your readiness probe so traffic stops routing before timeouts cascade."],"tags":["network","timeout","lasso","guardrails","httpx"],"backgroundTag":"api-request-timeout","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}