BerriAI/litellm · error · Exception
External Customer ID is not set. Charge_by={charge_by}. User
Error message
External Customer ID is not set. Charge_by={charge_by}. User_id={user_id}. End_user_id={end_user_id}. Team_id={team_id} What it means
Exception raised by the Lago integration when the identity field selected by LAGO_API_CHARGE_BY is None on the request, so there is no external_customer_id to attach the billing event to. The message dumps all three candidate ids for debugging.
Source
Thrown at litellm/integrations/lago.py:107
if os.getenv("LAGO_API_CHARGE_BY", None) is not None and isinstance(os.environ["LAGO_API_CHARGE_BY"], str):
if os.environ["LAGO_API_CHARGE_BY"] in [
"end_user_id",
"user_id",
"team_id",
]:
charge_by = os.environ["LAGO_API_CHARGE_BY"]
else:
raise Exception("invalid LAGO_API_CHARGE_BY set")
if charge_by == "end_user_id":
external_customer_id = end_user_id
elif charge_by == "team_id":
external_customer_id = team_id
elif charge_by == "user_id":
external_customer_id = user_id
if external_customer_id is None:
raise Exception(
f"External Customer ID is not set. Charge_by={charge_by}. User_id={user_id}. End_user_id={end_user_id}. Team_id={team_id}"
)
returned_val: Final = {
"event": {
"transaction_id": str(uuid.uuid4()),
"external_subscription_id": external_customer_id,
"code": os.getenv("LAGO_API_EVENT_CODE"),
"properties": {"model": model, "response_cost": cost, **usage},
}
}
verbose_logger.debug("\x1b[91mLogged Lago Object:\n%s\x1b[0m\n", returned_val)
return returned_val
def log_success_event(self, kwargs, response_obj, start_time, end_time):
_url = os.getenv("LAGO_API_BASE")
assert _url is not None and isinstance(_url, str), (View on GitHub (pinned to 6c2dcb801b)
Solutions
- Send the identity matching charge_by: user param / metadata user_id, team_id in metadata, or end-user id via litellm proxy user identification
- Switch LAGO_API_CHARGE_BY to the field you can reliably populate
- Ensure the proxy forwards these fields to the callback (metadata passthrough enabled)
Example fix
# before
litellm.completion(model='gpt-4o', messages=msgs) # no user identity
# after
litellm.completion(
model='gpt-4o',
messages=msgs,
user='user-123',
metadata={'user_id': 'user-123'},
) Defensive patterns
Strategy: validation
Validate before calling
import os
charge_by = os.getenv("LAGO_API_CHARGE_BY", "end_user_id")
identity = {"end_user_id": end_user_id, "user_id": user_id, "team_id": team_id}[charge_by]
if identity is None:
raise ValueError(
f"Request must carry a {charge_by}; cannot bill via Lago without it"
) Type guard
def has_billing_identity(charge_by: str, *, user_id, end_user_id, team_id) -> bool:
return {
"end_user_id": end_user_id,
"user_id": user_id,
"team_id": team_id,
}.get(charge_by) is not None Try / catch
try:
event = build_lago_event(...)
except Exception as e:
if "External Customer ID is not set" in str(e):
# log-and-continue: billing should not break inference
log.warning("Lago billing skipped: no identity for charge_by=%s", charge_by)
else:
raise Prevention
- Standardize on one identity field you can always populate, and set LAGO_API_CHARGE_BY to it
- Require user/metadata fields on all completion calls via middleware
- Treat billing failures as non-fatal to the inference path
When it happens
Trigger: LAGO_API_CHARGE_BY=user_id but the call carries no user param; charge_by=team_id without a team id in kwargs/metadata; default end_user_id with no end-user identified (no litellm_user_id / metadata end_user_id). Any of these yields None for the chosen field.
Common situations: Proxy deployments where clients don't send user identification; metadata keys not propagated (e.g. missing user / end_user_id in request metadata); charging by team_id while only user ids are supplied; testing with bare completion() calls.
Related errors
- Missing keys={missing_keys} in environment.
- invalid LAGO_API_CHARGE_BY set
- Error: {response.status_code} - {response.text}
- Missing Authorization header
- Invalid bearer token
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/fd626226e187fd37.
Report an issue: GitHub.