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
Base OCR transformation stub: the generic get_complete_url for OCR raises NotImplementedError because each OCR provider builds a different endpoint URL. Hitting it means a provider config was used that did not override URL construction, so litellm cannot know where to send the OCR request.
Source
Thrown at litellm/llms/base_llm/ocr/transformation.py:149
"""
Validate environment and return headers.
Override in provider-specific implementations.
"""
return headers
def get_complete_url(
self,
api_base: str | None,
model: str,
optional_params: dict,
litellm_params: dict | None = None,
**kwargs,
) -> str:
"""
Get complete URL for OCR endpoint.
Override in provider-specific implementations.
"""
raise NotImplementedError("get_complete_url must be implemented by provider")
def transform_ocr_request(
self,
model: str,
document: DocumentType,
optional_params: dict,
headers: dict,
**kwargs,
) -> OCRRequestData:
"""
Transform OCR request to provider-specific format.
Override in provider-specific implementations.
Note: By the time this method is called, any file-type documents have already
been converted to document_url/image_url format with base64 data URIs by
the preprocessing in litellm/ocr/main.py.
Args:View on GitHub (pinned to 6c2dcb801b)
Solutions
- Use a provider whose OCR config fully implements get_complete_url (e.g. the built-in azure/gemini document configs).
- Custom providers: override get_complete_url to return the provider's OCR endpoint.
- Verify the model string maps to the intended provider config in the provider registry.
- Upgrade litellm if the provider's OCR support landed in a newer release.
Example fix
# before
class MyOCRConfig(BaseOCRConfig): # no get_complete_url
...
litellm.ocr(model='my-proc/doc', document=doc)
# after
class MyOCRConfig(BaseOCRConfig):
def get_complete_url(self, api_base, model, optional_params, litellm_params=None, **kwargs):
return f'{api_base}/v1/documents:parse' Defensive patterns
Strategy: type-guard
Type guard
def ocr_config_is_complete(config) -> bool:
return type(config).get_complete_url is not BaseOCRConfig.get_complete_url Try / catch
try:
url = config.get_complete_url(api_base, model, {})
except NotImplementedError:
raise ConfigError(f'{type(config).__name__} lacks OCR URL construction; use a supported provider') from None Prevention
- At provider registration, assert required OCR hooks are overridden.
- Prefer built-in OCR providers unless you can implement the full contract.
- Pin litellm versions and re-run provider smoke tests on upgrade.
When it happens
Trigger: Calling litellm.ocr / the document-reading API with a provider whose config inherits the base get_complete_url (missing override); a new OCR integration half-implemented; provider name typo resolving to a generic config.
Common situations: Adding a custom OCR provider but only implementing transform_ocr_request; version skew where an older litellm lacks a concrete provider's URL method; dispatch selecting the base config due to unknown provider string.
Related errors
- transform_ocr_request must be implemented by provider
- transform_ocr_response must be implemented by provider
- Unclassified keys in {PRICES_PATH.name}: {', '.join(unclassi
- response must be of type OCRResponse got type={type(response
- OCR response usage_info is None
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/39520001e86faf5e.
Report an issue: GitHub.