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

  1. 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)
  2. Upgrade/downgrade litellm so integrations and core match: pip install -U litellm
  3. 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

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


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/cc62190e6a8b3432. Report an issue: GitHub.