BerriAI/litellm · error · NotImplementedError
transform_ocr_request must be implemented by provider
Error message
transform_ocr_request must be implemented by provider
What it means
Base OCR transformation stub for transform_ocr_request: converting the unified document input (document_url / image_url dict produced by litellm/ocr/main.py preprocessing) into a provider payload is provider-specific, so the base class raises NotImplementedError. A config without this override cannot serve OCR requests.
Source
Thrown at litellm/llms/base_llm/ocr/transformation.py:176
) -> 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:
model: Model name
document: Document to process - always a dict with type="document_url" or type="image_url"
optional_params: Optional parameters for the request
headers: Request headers
Returns:
OCRRequestData with data and files fields
"""
raise NotImplementedError("transform_ocr_request must be implemented by provider")
async def async_transform_ocr_request(
self,
model: str,
document: DocumentType,
optional_params: dict,
headers: dict,
**kwargs,
) -> OCRRequestData:
"""
Async transform OCR request to provider-specific format.
Optional method - providers can override if they need async transformations
(e.g., Azure AI for URL-to-base64 conversion).
Default implementation falls back to sync transform_ocr_request.
Args:
model: Model nameView on GitHub (pinned to 6c2dcb801b)
Solutions
- Implement transform_ocr_request in the provider config returning OCRRequestData(data=..., files=...).
- Confirm the provider string in the model name resolves to a concrete OCR config (check the provider registry).
- Switch to a supported OCR provider until the custom one is complete.
- Update litellm if support for the provider exists upstream.
Example fix
# before
class MyOCRConfig(BaseOCRConfig): ...
# NotImplementedError at request transform
# after
class MyOCRConfig(BaseOCRConfig):
def transform_ocr_request(self, model, document, optional_params, headers, **kwargs):
return OCRRequestData(data={'url': document['document_url']['url'], 'model': model}, files=None) Defensive patterns
Strategy: type-guard
Type guard
def can_transform_ocr_request(config) -> bool:
return type(config).transform_ocr_request is not BaseOCRConfig.transform_ocr_request Try / catch
try:
req = config.transform_ocr_request(model, document, optional_params, headers)
except NotImplementedError:
raise ConfigError('provider config incomplete: transform_ocr_request missing') from None Prevention
- Write the full provider contract (URL + request + response) before registering a config.
- Add unit tests exercising each hook directly on registered configs.
- Route unknown provider strings to an explicit error instead of the base config.
When it happens
Trigger: litellm.ocr() invoked with a provider config lacking transform_ocr_request; partially implemented custom OCR integration; provider resolution falling through to the base config (unknown custom_llm_provider).
Common situations: Contributing a new OCR provider and forgetting the request transform; model strings like 'ocr/my-provider' not matching any registered config; running an older litellm against docs for a newer provider integration.
Related errors
- get_complete_url must be implemented by provider
- transform_ocr_response must be implemented by provider
- ImageVariationConfig implementa 'transform_request_image_var
- Unclassified keys in {PRICES_PATH.name}: {', '.join(unclassi
- response must be of type OCRResponse got type={type(response
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/1189fa211e04eb71.
Report an issue: GitHub.