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
- Implement `def transform_search_request(self, query, optional_params, **kwargs) -> dict | list[dict]` in your custom config, mapping query/params into the provider schema.
- Or route the request to a built-in provider config that already implements it.
- 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
- Implement the full search-provider trio (url, request, response) in one commit; partial ports are the common cause.
- Unit-test request transformation against a recorded provider payload fixture.
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
- get_complete_url must be implemented by provider
- transform_search_response must be implemented by provider
- No Braintrust API token provided. Pass via Authorization hea
- File not found. banned_keywords_list={banned_keywords_list}
- validate_environment must be implemented by provider
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/384b09970ab79fa5.
Report an issue: GitHub.