BerriAI/litellm · error · NotImplementedError

transform_search_response must be implemented by provider

Error message

transform_search_response must be implemented by provider

What it means

BaseSearchConfig.transform_search_response() converts the provider's raw httpx.Response into LiteLLM's normalized SearchResponse. It is an abstract stub raising NotImplementedError. Encountering it means a search request succeeded at the HTTP layer but the active config never implemented response parsing (base class or incomplete custom provider), so results cannot be normalized.

Source

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

            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,
    ) -> Exception:
        """Get appropriate error class for the provider."""
        return BaseLLMException(
            status_code=status_code,
            message=error_message,
            headers=headers,
        )

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Implement `def transform_search_response(self, raw_response, logging_obj, **kwargs) -> SearchResponse` mapping provider JSON (results, titles, urls, snippets) into SearchResponse.
  2. Or use a built-in provider whose transformation is complete.
  3. Mirror the structure of an existing implementation (e.g. litellm/llms/gemini or exa search transformation) to satisfy the SearchResponse contract.

Example fix

# before
class MySearch(BaseSearchConfig):
    ...  # no transform_search_response -> NotImplementedError on 2xx

# after
from litellm.types.llms.openai import SearchResponse, SearchResponseResult

class MySearch(BaseSearchConfig):
    def transform_search_response(self, raw_response, logging_obj, **kwargs) -> SearchResponse:
        data = raw_response.json()
        return SearchResponse(results=[
            SearchResponseResult(title=r["title"], url=r["link"], snippet=r["snippet"])
            for r in data["items"]
        ])
Defensive patterns

Strategy: type-guard

Validate before calling

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

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

Type guard

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

def supports_search_response_transform(cfg: BaseSearchConfig) -> bool:
    return type(cfg).transform_search_response is not BaseSearchConfig.transform_search_response

Prevention

When it happens

Trigger: A provider returns 2xx from the search endpoint, then litellm calls transform_search_response on a config lacking the override — custom providers, or fallback-to-base routing.

Common situations: Custom search provider implementations that built and sent the request but never wrote the response mapper; schema drift after a litellm upgrade changed SearchResponse expectations.

Related errors


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