BerriAI/litellm · error · Exception

DataDogLLMObs: standard_logging_object is not set

Error message

DataDogLLMObs: standard_logging_object is not set

What it means

create_llm_obs_payload reads kwargs["standard_logging_object"] — the StandardLoggingPayload that litellm's core attaches during real logging hooks — and raises a plain Exception when it is missing. All callers in this class (async_log_success_event / async_log_failure_event) wrap payload creation in try/except and log the exception, so the visible symptom is an error line plus lost telemetry for that call, not a crash.

Source

Thrown at litellm/integrations/datadog/datadog_llm_obs.py:222

            if response.status_code != 202:
                raise Exception(
                    f"DataDogLLMObs: Unexpected response - status_code: {response.status_code}, text: {response.text}"
                )

            if self.is_mock_mode:
                verbose_logger.debug("[DATADOG MOCK] Batch of %s events successfully mocked", len(self.log_queue))
            else:
                verbose_logger.debug("DataDogLLMObs: Successfully sent batch - status_code: %s", response.status_code)
            self.log_queue.clear()
        except httpx.HTTPStatusError as e:
            verbose_logger.exception("DataDogLLMObs: Error sending batch - %s", e.response.text)
        except Exception as e:
            verbose_logger.exception("DataDogLLMObs: Error sending batch - %s", e)

    def create_llm_obs_payload(self, kwargs: dict, start_time: datetime, end_time: datetime) -> LLMObsPayload:
        standard_logging_payload: Final[StandardLoggingPayload | None] = kwargs.get("standard_logging_object")
        if standard_logging_payload is None:
            raise Exception("DataDogLLMObs: standard_logging_object is not set")

        messages = standard_logging_payload["messages"]
        messages = self._ensure_string_content(messages=messages)

        metadata: Final = kwargs.get("litellm_params", {}).get("metadata", {})

        input_meta: Final = InputMeta(messages=handle_any_messages_to_chat_completion_str_messages_conversion(messages))
        output_meta: Final = OutputMeta(
            messages=self._get_response_messages(
                standard_logging_payload=standard_logging_payload,
                call_type=standard_logging_payload.get("call_type"),
            )
        )

        error_info: Final = self._assemble_error_info(standard_logging_payload)

        metadata_parent_id: str | None = None
        if isinstance(metadata, dict):

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Drive the integration through a real litellm.completion call with the callback attached so standard_logging_object is populated
  2. If calling directly, attach a StandardLoggingPayload to kwargs first (build one with litellm's get_standard_logging_payload helpers)
  3. Align litellm package versions (single install) so the hook contract holds

Example fix

# before
def test_payload():
    kwargs = {"model": "gpt-4"}
    logger.create_llm_obs_payload(kwargs, start, end)  # Exception

# after
def test_payload(standard_logging_payload):
    kwargs = {"model": "gpt-4", "standard_logging_object": standard_logging_payload}
    logger.create_llm_obs_payload(kwargs, start, end)
Defensive patterns

Strategy: validation

Validate before calling

def safe_create_llm_obs_payload(logger, kwargs, start, end):
    if kwargs.get("standard_logging_object") is None:
        return None  # skip rather than raise
    return logger.create_llm_obs_payload(kwargs, start, end)

Type guard

from typing import Any

def has_slo(kwargs: Any) -> bool:
    """True when kwargs came from litellm's real logging hooks."""
    return isinstance(kwargs, dict) and isinstance(kwargs.get("standard_logging_object"), dict)

Try / catch

try:
    payload = logger.create_llm_obs_payload(kwargs, start_time, end_time)
except Exception as e:  # callers in this class do exactly this; mirror it in custom code
    litellm.verbose_logger.exception("llm-obs payload skipped: %s", e)
    payload = None

Prevention

When it happens

Trigger: Invoking create_llm_obs_payload directly (tests, custom orchestration) with kwargs lacking the key; manually calling async_log_success_event with fabricated kwargs; version skew between the integration and a litellm core that no longer populates the object.

Common situations: Unit tests for the datadog LLM-obs integration that build kwargs by hand; forks pinning an old litellm core with a new integrations package.

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/b0177f3b7bea839e. Report an issue: GitHub.