BerriAI/litellm · warning · ValueError

standard_logging_object not found in kwargs

Error message

standard_logging_object not found in kwargs

What it means

Literal AI's logger requires kwargs['standard_logging_object'] (LiteLLM's normalized StandardLoggingPayload) to build its run data; _prepare_log_data raises ValueError when it is None. In the normal litellm pipeline this payload is always created before success callbacks fire, so seeing this means the logging hook was invoked with hand-made or incomplete kwargs.

Source

Thrown at litellm/integrations/literal_ai.py:168

                    "query": query,
                    "variables": variables,
                },
                headers=self.headers,
            )
            if response.status_code >= 300:
                verbose_logger.error("Literal AI Error: %s - %s", response.status_code, response.text)
            else:
                verbose_logger.debug("Batch of %s runs successfully created", len(self.log_queue))
        except httpx.HTTPStatusError as e:
            verbose_logger.exception("Literal AI HTTP Error: %s - %s", e.response.status_code, e.response.text)
        except Exception:
            verbose_logger.exception("Literal AI Layer Error")

    def _prepare_log_data(self, kwargs, response_obj, start_time, end_time) -> dict:
        logging_payload: Final[StandardLoggingPayload | None] = kwargs.get("standard_logging_object", None)

        if logging_payload is None:
            raise ValueError("standard_logging_object not found in kwargs")
        clean_metadata: Final = logging_payload["metadata"]
        metadata: Final = kwargs.get("litellm_params", {}).get("metadata", {})

        settings: Final = logging_payload["model_parameters"]
        messages: Final = logging_payload["messages"]
        response: Final = logging_payload["response"]
        choices: list = []
        if isinstance(response, dict) and "choices" in response:
            choices = response["choices"]
        message_completion: Final = choices[0]["message"] if choices else None
        prompt_id = None
        variables = None

        if messages and isinstance(messages, list) and isinstance(messages[0], dict):
            for message in messages:
                if literal_prompt := getattr(message, "__literal_prompt__", None):
                    prompt_id = literal_prompt.get("prompt_id")
                    variables = literal_prompt.get("variables")

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Route tests through litellm.completion(..., success_callback=['literalai']) so the standard payload is built by the framework
  2. If calling _prepare_log_data directly, include a valid StandardLoggingPayload dict under kwargs['standard_logging_object'] (with metadata, model_parameters, messages, response keys)
  3. Check any custom middleware that mutates kwargs before callbacks and stop it from dropping the key
  4. Align the litellm version between the app and any copied callback code

Example fix

# before
await logger.async_log_success_event(
    kwargs={"litellm_params": {"metadata": {}}},  # ValueError
    response_obj=resp, start_time=t0, end_time=t1,
)

# after
kwargs = {
    "standard_logging_object": {
        "metadata": {}, "model_parameters": {},
        "messages": [], "response": {"choices": []},
    },
    "litellm_params": {"metadata": {}},
}
await logger.async_log_success_event(kwargs=kwargs, response_obj=resp, start_time=t0, end_time=t1)
Defensive patterns

Strategy: try-catch

Validate before calling

def has_standard_logging_payload(kwargs: dict) -> bool:
    payload = kwargs.get("standard_logging_object")
    return isinstance(payload, dict) and {"metadata", "messages", "response"} <= set(payload)

Try / catch

try:
    data = logger._prepare_log_data(kwargs, response_obj, start, end)
except ValueError as e:
    if "standard_logging_object" in str(e):
        return  # hook invoked without framework-built payload; skip
    raise

Prevention

When it happens

Trigger: Unit-testing the LiteralAI logger with synthetic kwargs; calling async_log_success_event/log_success_event directly; middleware or wrappers that strip or replace kwargs before the callback chain; version skew where the payload key moved.

Common situations: Custom test harnesses for callback integrations; forks invoking internal logging APIs; upgrading litellm across versions that changed standard_logging_object construction.

Related errors


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