BerriAI/litellm · error · ProxyException

End User Id(s)={} do not exist in db

Error message

End User Id(s)={} do not exist in db

What it means

POST /customer/delete pre-fetches all requested user_ids with find_many; if any id has no row it returns a 404 not_found ProxyException (param=user_ids) listing exactly which ids do not exist, and deletes nothing - delete_many only runs when every requested id resolves.

Source

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

    ```
    """
    from litellm.proxy.proxy_server import prisma_client

    try:
        if prisma_client is None:
            raise Exception("Not connected to DB!")

        verbose_proxy_logger.debug("/customer/delete: Received data = %s", data)
        if data.user_ids is not None and isinstance(data.user_ids, list) and len(data.user_ids) > 0:
            # First check if all users exist
            existing_users: Final = await _typed_table(EndUserRepository(prisma_client)).find_many(
                where={"user_id": {"in": data.user_ids}}
            )
            existing_user_ids: Final = {user.user_id for user in existing_users}
            missing_user_ids: Final = [user_id for user_id in data.user_ids if user_id not in existing_user_ids]

            if missing_user_ids:
                raise ProxyException(
                    message="End User Id(s)={} do not exist in db".format(", ".join(missing_user_ids)),
                    type="not_found",
                    code=404,
                    param="user_ids",
                )

            # All users exist, proceed with deletion
            response: Final = await _typed_table(EndUserRepository(prisma_client)).delete_many(
                where={"user_id": {"in": data.user_ids}}
            )
            verbose_proxy_logger.debug("received response from updating prisma client. response=%s", response)

            await _evict_end_user_cache_keys(_end_user_cache_keys(data.user_ids))

            return DeleteCustomersResponse(
                deleted_customers=response,
                message="Successfully deleted customers with ids: " + str(data.user_ids),
            )

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Reconcile first: GET /customer/list and delete only ids that still exist
  2. Make delete jobs idempotent - treat already-missing ids as successfully deleted
  3. Retry with the valid subset: the error message itself prints the missing ids to drop

Example fix

# before
resp = post("/customer/delete", {"user_ids": ["a", "b", "c"]})  # "c" already gone -> 404, nothing deleted

# after
missing = {"c"}
resp = post("/customer/delete", {"user_ids": [i for i in ids if i not in missing]})
Defensive patterns

Strategy: validation

Validate before calling

import httpx


def split_deletable(base: str, headers: dict, user_ids: list[str]) -> tuple[list[str], list[str]]:
    listed = {c["user_id"] for c in httpx.get(f"{base}/customer/list", headers=headers).json()}
    return [i for i in user_ids if i in listed], [i for i in user_ids if i not in listed]

Try / catch

try:
    r = httpx.post(f"{base}/customer/delete", json={"user_ids": ids}, headers=headers)
except httpx.HTTPStatusError as e:
    if e.response.status_code == 404 and "do not exist" in e.response.text:
        missing = e.response.json()["detail"]["error"].split("End User Id(s)=")[1].split(" do not")[0]
        ids = [i for i in ids if i not in missing.split(", ")]
        return httpx.post(f"{base}/customer/delete", json={"user_ids": ids}, headers=headers)
    raise

Prevention

When it happens

Trigger: POST /customer/delete with a batch containing at least one unknown id: deleted by an earlier run, never created, or differing by casing/whitespace.

Common situations: Re-running non-idempotent delete scripts whose previous attempt removed part of the batch; concurrent deletes from two jobs; batch payloads assembled from stale exports.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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