BerriAI/litellm · error · HTTPException

{e}

Error message

{e}

What it means

The catch-all handler at the bottom of POST /customer/block: any non-HTTPException error raised while upserting end-user rows or evicting end-user cache keys is logged via verbose_proxy_logger ('An error occurred - <e>') and re-raised as HTTP 500 whose detail is the original exception text. The catalog message '{e}' is dynamic - it mirrors whatever the underlying failure reported.

Source

Thrown at litellm/proxy/management_endpoints/customer_endpoints.py:188

                record = await _typed_table(EndUserRepository(prisma_client)).upsert(
                    where={"user_id": id},
                    data={
                        "create": {"user_id": id, "blocked": True},
                        "update": {"blocked": True},
                    },
                )
                records.append(record)
            await _evict_end_user_cache_keys(_end_user_cache_keys(data.user_ids))
        else:
            raise HTTPException(
                status_code=500,
                detail={"error": "Postgres DB Not connected"},
            )

        return {"blocked_users": records}
    except Exception as e:
        verbose_proxy_logger.error("An error occurred - %s", e)
        raise HTTPException(status_code=500, detail={"error": str(e)})


@router.post(
    "/end_user/unblock",
    tags=["Customer Management"],
    dependencies=[Depends(user_api_key_auth)],
    include_in_schema=False,
)
@router.post(
    "/customer/unblock",
    tags=["Customer Management"],
    dependencies=[Depends(user_api_key_auth)],
    response_model=UnblockUsersResponse,
)
async def unblock_user(data: BlockUsers):
    """
    [BETA] Unblock calls with this user id

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Read the 500's detail string and the proxy log line 'An error occurred - ...' - they carry the real cause
  2. If it is a DB error, restore connectivity and confirm migrations are applied, then retry
  3. If it is cache eviction (Redis), fix or relax the cache backend and re-send the request
  4. Re-send safely on recovery: each user_id is upserted, so partial progress is idempotent
Defensive patterns

Strategy: try-catch

Try / catch

import httpx


def block_users(base: str, headers: dict, user_ids: list[str]) -> dict:
    r = httpx.post(f"{base}/customer/block", json={"user_ids": user_ids}, headers=headers)
    if r.status_code >= 500:
        detail = str(r.json().get("detail", ""))  # raw underlying exception text
        if "Not connected" in detail:
            raise RuntimeError("proxy has no database configured") from None
        raise RuntimeError(f"proxy internal error, check proxy logs: {detail}")
    r.raise_for_status()
    return r.json()

Prevention

When it happens

Trigger: Any unexpected exception inside the block loop: a Prisma query failure (constraint, connection drop, stale schema), an error while appending records, or a failure in _evict_end_user_cache_keys (e.g. Redis unreachable).

Common situations: Database restarted while blocking a batch of users; Prisma schema drift after upgrading the proxy image without applying migrations; cache backend (Redis) outage making cache eviction raise after the DB write already succeeded.

Related errors


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