{"record":{"id":"cc62190e6a8b3432","repo":"BerriAI/litellm","slug":"standard-logging-object-is-required-got-standard","errorCode":null,"errorMessage":"standard_logging_object is required, got={standard_logging_payload}","messagePattern":"standard_logging_object is required, got=(.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/integrations/prometheus.py","lineNumber":1267,"sourceCode":"            supported_enum_labels=self.get_labels_for_metric(metric_name=metric_name),\n            enum_values=enum_values,\n            label_context=label_context,\n        )\n        counter.labels(**_labels).inc(amount)\n        self._track_end_user_metric_series(counter, metric_name, _labels)\n\n    async def async_log_success_event(self, kwargs, response_obj, start_time, end_time):\n        # Define prometheus client\n        verbose_logger.debug(\n            \"prometheus Logging - Enters success logging function (kwargs keys: %s)\",\n            list(kwargs.keys()) if isinstance(kwargs, dict) else type(kwargs).__name__,\n        )\n\n        # unpack kwargs\n        standard_logging_payload: Final[StandardLoggingPayload | None] = kwargs.get(\"standard_logging_object\")\n\n        if standard_logging_payload is None or not isinstance(standard_logging_payload, dict):\n            raise ValueError(f\"standard_logging_object is required, got={standard_logging_payload}\")\n\n        if self._should_skip_metrics_for_invalid_key(kwargs=kwargs, standard_logging_payload=standard_logging_payload):\n            return\n\n        model: Final = kwargs.get(\"model\", \"\")\n        litellm_params: Final = kwargs.get(\"litellm_params\", {}) or {}\n        _metadata: Final = litellm_params.get(\"metadata\") or {}\n        get_end_user_id_for_cost_tracking: Final = _get_cached_end_user_id_for_cost_tracking()\n\n        end_user_id: Final = get_end_user_id_for_cost_tracking(litellm_params, service_type=\"prometheus\")\n        user_id: Final = standard_logging_payload[\"metadata\"][\"user_api_key_user_id\"]\n        user_api_key = standard_logging_payload[\"metadata\"][\"user_api_key_hash\"]\n        user_api_key_alias: Final = standard_logging_payload[\"metadata\"][\"user_api_key_alias\"]\n        user_api_team: Final = standard_logging_payload[\"metadata\"][\"user_api_key_team_id\"]\n        user_api_team_alias: Final = standard_logging_payload[\"metadata\"][\"user_api_key_team_alias\"]\n        user_api_key_org_id: Final = standard_logging_payload[\"metadata\"].get(\"user_api_key_org_id\")\n        user_api_key_org_alias: Final = standard_logging_payload[\"metadata\"].get(\"user_api_key_org_alias\")\n        output_tokens: Final = standard_logging_payload[\"completion_tokens\"]","sourceCodeStart":1249,"sourceCodeEnd":1285,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/integrations/prometheus.py#L1249-L1285","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before\nawait prometheus_logger.async_log_success_event(\n    {\"model\": \"gpt-4o\"}, response_obj, start_time, end_time\n)  # ValueError: standard_logging_object is required\n\n# after\nfrom litellm.litellm_core_utils.standard_logging_payload import StandardLoggingPayload\nkwargs = {\n    \"model\": \"gpt-4o\",\n    \"standard_logging_object\": {\n        \"id\": \"chatcmpl-123\",\n        \"call_type\": \"acompletion\",\n        \"metadata\": {\"user_api_key_hash\": \"sk-...\", \"user_api_key_user_id\": \"u1\"},\n        \"response_obj\": response_obj,\n    },\n}\nawait prometheus_logger.async_log_success_event(kwargs, response_obj, start_time, end_time)","handlingStrategy":"validation","validationCode":"def has_standard_logging_payload(kwargs: dict) -> bool:\n    p = kwargs.get(\"standard_logging_object\")\n    return isinstance(p, dict) and isinstance(p.get(\"metadata\"), dict)\n\n# before awaiting the callback (tests / custom pipelines):\nif not has_standard_logging_payload(kwargs):\n    skip_or_build_payload(kwargs)","typeGuard":"from typing import Any, TypeGuard\nfrom litellm.integrations.prometheus import StandardLoggingPayload\n\ndef is_standard_logging_payload(v: Any) -> TypeGuard[StandardLoggingPayload]:\n    return isinstance(v, dict) and isinstance(v.get(\"metadata\"), dict) and \"user_api_key_hash\" in v[\"metadata\"]","tryCatchPattern":"try:\n    await logger.async_log_success_event(kwargs, resp, t0, t1)\nexcept ValueError as e:\n    if \"standard_logging_object is required\" in str(e):\n        logging.warning(\"prometheus callback skipped: no standard logging payload\")\n    else:\n        raise","preventionTips":["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"],"tags":["prometheus","metrics","callbacks","standard-logging-object","kwargs"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}