BerriAI/litellm · error · ValueError

optional_params is required

Error message

optional_params is required

What it means

validate_input_kwargs raises when 'optional_params' is absent or not a dict. optional_params carries the cleaned inference parameters (temperature, stream, tools, ...) that the bridge maps onto the Responses API request. Missing it means the internal completion pipeline contract was broken — it is always populated by get_optional_params in normal litellm.completion flows.

Source

Thrown at litellm/completion_extras/litellm_responses_transformation/handler.py:122

        from litellm.types.utils import ModelResponse

        typed_kwargs: Final[dict[str, object]] = kwargs

        model: Final = typed_kwargs.get("model")
        if model is None or not isinstance(model, str):
            raise ValueError("model is required")

        custom_llm_provider: Final = typed_kwargs.get("custom_llm_provider")
        if custom_llm_provider is None or not isinstance(custom_llm_provider, str):
            raise ValueError("custom_llm_provider is required")

        messages: Final = typed_kwargs.get("messages")
        if messages is None or not isinstance(messages, list):
            raise ValueError("messages is required")

        optional_params: Final = typed_kwargs.get("optional_params")
        if optional_params is None or not isinstance(optional_params, dict):
            raise ValueError("optional_params is required")

        litellm_params: Final = typed_kwargs.get("litellm_params")
        if litellm_params is None or not isinstance(litellm_params, dict):
            raise ValueError("litellm_params is required")

        headers: Final = typed_kwargs.get("headers")
        if headers is None or not isinstance(headers, dict):
            raise ValueError("headers is required")

        model_response: Final = typed_kwargs.get("model_response")
        if model_response is None or not isinstance(model_response, ModelResponse):
            raise ValueError("model_response is required")

        logging_obj: Final = typed_kwargs.get("logging_obj")
        if logging_obj is None or not isinstance(logging_obj, LiteLLMLoggingObj):
            raise ValueError("logging_obj is required")

        return ResponsesToCompletionBridgeHandlerInputKwargs(

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Route through litellm.completion so optional_params is built by get_optional_params
  2. If direct, pass at minimum an empty dict: optional_params={}
  3. Regenerate any hand-copied kwargs template against the current ResponsesToCompletionBridgeHandlerInputKwargs definition

Example fix

# before
kwargs = {"model": m, "messages": msgs}  # optional_params missing

# after
kwargs = {"model": m, "messages": msgs, "optional_params": {}}
Defensive patterns

Strategy: validation

Validate before calling

def has_optional_params(kwargs: dict) -> bool:
    return isinstance(kwargs.get("optional_params"), dict)

Type guard

def is_dict_param(v) -> bool:
    return isinstance(v, dict)

Prevention

When it happens

Trigger: Direct bridge handler invocation with a kwargs dict that omits optional_params or sets it to None; a fork that renames the key.

Common situations: Custom integrations building kwargs by hand; version drift after upgrading litellm where optional_params construction moved earlier/later in the pipeline.

Related errors


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