BerriAI/litellm · error · NotImplementedError
get_complete_url must be implemented by provider
Error message
get_complete_url must be implemented by provider
What it means
BaseSearchConfig.get_complete_url() is an abstract hook that must build the full search endpoint URL (some providers like Google PSE encode the query into GET query params using the transformed body). The base class raises NotImplementedError. Hitting it means a search request was routed to a config that never implemented URL construction — the base class or an incomplete custom provider.
Source
Thrown at litellm/llms/base_llm/search/transformation.py:211
"""
Get complete URL for Search endpoint.
Args:
api_base: Base URL for the API
optional_params: Optional parameters for the request
data: Transformed request body from transform_search_request().
Some providers (e.g., Google PSE) use GET requests and need
the request body to construct query parameters in the URL.
Can be a dict or list of dicts depending on provider.
**kwargs: Additional keyword arguments
Returns:
Complete URL for the search endpoint
Note:
Override in provider-specific implementations.
"""
raise NotImplementedError("get_complete_url must be implemented by provider")
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
"""View on GitHub (pinned to 6c2dcb801b)
Solutions
- Use a built-in search provider config that implements get_complete_url (e.g. the Google PSE / Exa / Tavily configs in litellm/llms/*/search/transformation.py) as your template.
- In your custom config, implement `def get_complete_url(self, api_base, api_key, query, data, **kwargs) -> str` returning the full endpoint URL.
- Verify the provider name you pass resolves to your concrete class, not BaseSearchConfig.
Example fix
# before
class MySearch(BaseSearchConfig):
pass # -> NotImplementedError('get_complete_url must be implemented by provider')
# after
class MySearch(BaseSearchConfig):
def get_complete_url(self, api_base, api_key, query, data, **kwargs) -> str:
return f"{api_base or 'https://api.mysearch.io'}/v1/search" Defensive patterns
Strategy: type-guard
Validate before calling
from litellm.llms.base_llm.search.transformation import BaseSearchConfig assert type(cfg).get_complete_url is not BaseSearchConfig.get_complete_url, "get_complete_url not implemented"
Type guard
from litellm.llms.base_llm.search.transformation import BaseSearchConfig
def search_config_is_complete(cfg: BaseSearchConfig) -> bool:
return all(
getattr(type(cfg), m) is not getattr(BaseSearchConfig, m)
for m in ("get_complete_url", "transform_search_request", "transform_search_response")
) Prevention
- Model custom search providers on an existing built-in config so all three hooks get implemented.
- Add interface-conformance tests for every custom provider config in CI.
When it happens
Trigger: Invoking litellm search (provider web-search path) with a provider whose config class does not override get_complete_url — e.g. registering a custom search provider that only partially implements the interface, or a version mismatch where a new provider was expected to supply it.
Common situations: Adding a custom search backend (internal enterprise search) and missing the URL builder; copying an example config that predates the interface; provider handler registered under the wrong class.
Related errors
- validate_environment must be implemented by provider
- transform_search_request must be implemented by provider
- transform_search_response must be implemented by provider
- acreate_sandbox must be implemented by provider
- arun_code must be implemented by provider
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/4221284972995067.
Report an issue: GitHub.