BerriAI/litellm · error · ValueError

user_id is required, passed user_id = {data.user_id}

Error message

user_id is required, passed user_id = {data.user_id}

What it means

POST /customer/update requires a non-empty user_id; when it is None or '' the endpoint raises ValueError('user_id is required, passed user_id = ...') which handle_exception_on_proxy surfaces as HTTP 500. Note it is a 500, not a 422, despite being purely a client payload problem.

Source

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

            update_end_user_table_data.pop("object_permission", None)

        if data.user_id is not None and len(data.user_id) > 0:
            update_end_user_table_data["user_id"] = data.user_id
            verbose_proxy_logger.debug("In update customer, user_id condition block.")
            response: Final = await _typed_table(EndUserRepository(prisma_client)).update(
                where={"user_id": data.user_id},
                data=update_end_user_table_data,
                include={"litellm_budget_table": True, "object_permission": True},
            )
            if response is None:
                raise ValueError(f"Failed updating customer data. User ID does not exist passed user_id={data.user_id}")
            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_id,)))

            return _to_customer_response(response)
        else:
            raise ValueError(f"user_id is required, passed user_id = {data.user_id}")

        # update based on remaining passed in values

    except Exception as e:
        verbose_proxy_logger.exception("litellm.proxy.proxy_server.update_end_user(): Exception occured - %s", e)
        raise handle_exception_on_proxy(e)


@router.post(
    "/customer/delete",
    tags=["Customer Management"],
    dependencies=[Depends(user_api_key_auth)],
    response_model=DeleteCustomersResponse,
)
@router.post(
    "/end_user/delete",
    tags=["Customer Management"],
    include_in_schema=False,

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Always include a non-empty user_id in the update body
  2. Validate the payload client-side with a required-user_id schema before sending
  3. Treat this 500 as a client payload bug in monitoring - it is not a proxy outage

Example fix

# before
resp = httpx.post(f"{base}/customer/update", json={"blocked": True}, headers=headers)   # no user_id -> 500

# after
resp = httpx.post(f"{base}/customer/update", json={"user_id": "cust-42", "blocked": True}, headers=headers)
Defensive patterns

Strategy: validation

Validate before calling

def has_required_user_id(payload: dict) -> bool:
    uid = payload.get("user_id")
    return isinstance(uid, str) and len(uid.strip()) > 0

Type guard

from typing import TypeGuard


def is_valid_update_payload(payload: dict) -> TypeGuard[dict]:
    """Narrows to payloads safe to send to POST /customer/update."""
    uid = payload.get("user_id")
    return isinstance(uid, str) and len(uid.strip()) > 0

Try / catch

try:
    r = httpx.post(f"{base}/customer/update", json=payload, headers=headers)
except httpx.HTTPStatusError as e:
    if e.response.status_code == 500 and "user_id is required" in e.response.text:
        raise ValueError("update payload must include a non-empty user_id") from e
    raise

Prevention

When it happens

Trigger: POST /customer/update omitting user_id from the JSON body, sending null, or sending an empty string.

Common situations: Partial-update clients that only send changed fields; pydantic/TypedDict models defaulting user_id to None; JSON key typos like userId that silently drop the field.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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