BerriAI/litellm · error · NotImplementedError

transform_search_request must be implemented by provider

Error message

transform_search_request must be implemented by provider

What it means

BaseSearchConfig.transform_search_request() is the abstract hook converting a normalized search query (str or list[str]) plus optional_params into the provider's request body. The base raises NotImplementedError. The error means the search path executed against the base/incomplete config, so no provider payload could be built.

Source

Thrown at litellm/llms/base_llm/search/transformation.py:230

    def transform_search_request(
        self,
        query: str | list[str],
        optional_params: dict,
        **kwargs,
    ) -> dict | list[dict]:
        """
        Transform Search request to provider-specific format.
        Override in provider-specific implementations.

        Args:
            query: Search query (string or list of strings)
            optional_params: Optional parameters for the request

        Returns:
            Dict with request data
        """
        raise NotImplementedError("transform_search_request must be implemented by provider")

    def transform_search_response(
        self,
        raw_response: httpx.Response,
        logging_obj: LiteLLMLoggingObj,
        **kwargs,
    ) -> SearchResponse:
        """
        Transform provider-specific Search response to standard format.
        Override in provider-specific implementations.
        """
        raise NotImplementedError("transform_search_response must be implemented by provider")

    def get_error_class(
        self,
        error_message: str,
        status_code: int,
        headers: dict,

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Implement `def transform_search_request(self, query, optional_params, **kwargs) -> dict | list[dict]` in your custom config, mapping query/params into the provider schema.
  2. Or route the request to a built-in provider config that already implements it.
  3. Add unit tests instantiating each custom search config and calling all four hooks to catch gaps before runtime.

Example fix

# before
class MySearch(BaseSearchConfig):
    def get_complete_url(self, *a, **k): ...
    # no transform_search_request -> NotImplementedError

# after
class MySearch(BaseSearchConfig):
    def transform_search_request(self, query, optional_params, **kwargs):
        return {"q": query, "num": optional_params.get("num_results", 10), **optional_params}
Defensive patterns

Strategy: type-guard

Validate before calling

from litellm.llms.base_llm.search.transformation import BaseSearchConfig

assert type(cfg).transform_search_request is not BaseSearchConfig.transform_search_request

Type guard

from litellm.llms.base_llm.search.transformation import BaseSearchConfig

def supports_search_request_transform(cfg: BaseSearchConfig) -> bool:
    return type(cfg).transform_search_request is not BaseSearchConfig.transform_search_request

Prevention

When it happens

Trigger: litellm.search(...) dispatching to a search config that does not override transform_search_request — custom providers with partial implementations, or a misregistered handler.

Common situations: Implementing a custom search provider and finishing get_complete_url but not the body transformer; upgrading litellm to a version that formalized this interface on your subclass.

Related errors


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