BerriAI/litellm · error · ValueError
standard_logging_object is required, got={standard_logging_p
Error message
standard_logging_object is required, got={standard_logging_payload} What it means
PrometheusLogger.async_log_success_event requires kwargs['standard_logging_object'] — the standardized logging payload (model, tokens, spend, metadata) that LiteLLM's logging pipeline attaches to every proxied LLM call. If the key is missing or not a dict, the callback raises ValueError before any metric is emitted, because every subsequent line (user_api_key_user_id, spend, etc.) reads from that payload.
Source
Thrown at litellm/integrations/prometheus.py:1267
supported_enum_labels=self.get_labels_for_metric(metric_name=metric_name),
enum_values=enum_values,
label_context=label_context,
)
counter.labels(**_labels).inc(amount)
self._track_end_user_metric_series(counter, metric_name, _labels)
async def async_log_success_event(self, kwargs, response_obj, start_time, end_time):
# Define prometheus client
verbose_logger.debug(
"prometheus Logging - Enters success logging function (kwargs keys: %s)",
list(kwargs.keys()) if isinstance(kwargs, dict) else type(kwargs).__name__,
)
# unpack kwargs
standard_logging_payload: Final[StandardLoggingPayload | None] = kwargs.get("standard_logging_object")
if standard_logging_payload is None or not isinstance(standard_logging_payload, dict):
raise ValueError(f"standard_logging_object is required, got={standard_logging_payload}")
if self._should_skip_metrics_for_invalid_key(kwargs=kwargs, standard_logging_payload=standard_logging_payload):
return
model: Final = kwargs.get("model", "")
litellm_params: Final = kwargs.get("litellm_params", {}) or {}
_metadata: Final = litellm_params.get("metadata") or {}
get_end_user_id_for_cost_tracking: Final = _get_cached_end_user_id_for_cost_tracking()
end_user_id: Final = get_end_user_id_for_cost_tracking(litellm_params, service_type="prometheus")
user_id: Final = standard_logging_payload["metadata"]["user_api_key_user_id"]
user_api_key = standard_logging_payload["metadata"]["user_api_key_hash"]
user_api_key_alias: Final = standard_logging_payload["metadata"]["user_api_key_alias"]
user_api_team: Final = standard_logging_payload["metadata"]["user_api_key_team_id"]
user_api_team_alias: Final = standard_logging_payload["metadata"]["user_api_key_team_alias"]
user_api_key_org_id: Final = standard_logging_payload["metadata"].get("user_api_key_org_id")
user_api_key_org_alias: Final = standard_logging_payload["metadata"].get("user_api_key_org_alias")
output_tokens: Final = standard_logging_payload["completion_tokens"]View on GitHub (pinned to 6c2dcb801b)
Solutions
- If invoking the callback manually, pass a valid standard_logging_object dict in kwargs (built via litellm.litellm_core_utils.standard_logging_payload or copied from a real logged call)
- Upgrade/downgrade litellm so integrations and core match: pip install -U litellm
- If this fires on real proxy traffic, capture kwargs keys (the debug line above the raise logs them) and check for a custom router/middleware stripping kwargs
Example fix
# before
await prometheus_logger.async_log_success_event(
{"model": "gpt-4o"}, response_obj, start_time, end_time
) # ValueError: standard_logging_object is required
# after
from litellm.litellm_core_utils.standard_logging_payload import StandardLoggingPayload
kwargs = {
"model": "gpt-4o",
"standard_logging_object": {
"id": "chatcmpl-123",
"call_type": "acompletion",
"metadata": {"user_api_key_hash": "sk-...", "user_api_key_user_id": "u1"},
"response_obj": response_obj,
},
}
await prometheus_logger.async_log_success_event(kwargs, response_obj, start_time, end_time) Defensive patterns
Strategy: validation
Validate before calling
def has_standard_logging_payload(kwargs: dict) -> bool:
p = kwargs.get("standard_logging_object")
return isinstance(p, dict) and isinstance(p.get("metadata"), dict)
# before awaiting the callback (tests / custom pipelines):
if not has_standard_logging_payload(kwargs):
skip_or_build_payload(kwargs) Type guard
from typing import Any, TypeGuard
from litellm.integrations.prometheus import StandardLoggingPayload
def is_standard_logging_payload(v: Any) -> TypeGuard[StandardLoggingPayload]:
return isinstance(v, dict) and isinstance(v.get("metadata"), dict) and "user_api_key_hash" in v["metadata"] Try / catch
try:
await logger.async_log_success_event(kwargs, resp, t0, t1)
except ValueError as e:
if "standard_logging_object is required" in str(e):
logging.warning("prometheus callback skipped: no standard logging payload")
else:
raise Prevention
- Always run prometheus metrics through the standard proxy/logging lifecycle rather than invoking the callback directly
- In tests, build kwargs with litellm's payload helpers or reuse a recorded real payload instead of hand-writing minimal dicts
- Pin litellm to one version so integrations and core always agree on the payload contract
When it happens
Trigger: The prometheus callback runs on a code path that never built the standard logging payload: invoking async_log_success_event directly (e.g. in tests with synthetic kwargs), calling a stripped-down completion path that bypasses litellm's Logging callback lifecycle, or a partially-upgraded install where the callback version expects the payload but the core does not attach it.
Common situations: Adding 'prometheus' to litellm.callbacks in a standalone script instead of the proxy; unit tests that fabricate kwargs without standard_logging_object; version drift between litellm.integrations and litellm_core_utils after a partial upgrade.
Related errors
- PROMETHEUS_URL not set please set 'PROMETHEUS_URL=<>' in .en
- Missing prometheus_client. Run `pip install prometheus-clien
- model is required
- otel.attributes: {TOKEN_TYPE_ATTRIBUTE} is a structural toke
- Promptlayer did not successfully log the response!
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/cc62190e6a8b3432.
Report an issue: GitHub.