{"record":{"id":"3f6abd27668f9643","repo":"BerriAI/litellm","slug":"transform-ocr-response-must-be-implemented-by-prov","errorCode":null,"errorMessage":"transform_ocr_response must be implemented by provider","messagePattern":"transform_ocr_response must be implemented by provider","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"litellm/llms/base_llm/ocr/transformation.py","lineNumber":222,"sourceCode":"            model=model,\n            document=document,\n            optional_params=optional_params,\n            headers=headers,\n            **kwargs,\n        )\n\n    def transform_ocr_response(\n        self,\n        model: str,\n        raw_response: httpx.Response,\n        logging_obj: LiteLLMLoggingObj,\n        **kwargs,\n    ) -> OCRResponse:\n        \"\"\"\n        Transform provider-specific OCR response to standard format.\n        Override in provider-specific implementations.\n        \"\"\"\n        raise NotImplementedError(\"transform_ocr_response must be implemented by provider\")\n\n    async def async_transform_ocr_response(\n        self,\n        model: str,\n        raw_response: httpx.Response,\n        logging_obj: LiteLLMLoggingObj,\n        **kwargs,\n    ) -> OCRResponse:\n        \"\"\"\n        Async transform provider-specific OCR response to standard format.\n        Optional method - providers can override if they need async transformations\n        (e.g., Azure Document Intelligence for async operation polling).\n\n        Default implementation falls back to sync transform_ocr_response.\n\n        Args:\n            model: Model name\n            raw_response: Raw HTTP response","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/llms/base_llm/ocr/transformation.py#L204-L240","documentation":"Base OCR transformation stub for transform_ocr_response: mapping a provider's raw httpx.Response to the standard OCRResponse is provider-specific, so the base class raises NotImplementedError. Seeing it means the request may have even succeeded at HTTP level but no response parser was wired in the active config.","triggerScenarios":"A provider config without transform_ocr_response reached the response-handling stage of an OCR call; async providers overriding only async_transform_ocr_response but invoked on a sync path (or vice versa); base config selected via misrouted provider name.","commonSituations":"Custom OCR integrations that stop at request building; sync/async method mismatches; version skew between litellm core and provider configs.","solutions":["Implement transform_ocr_response in the config to build OCRResponse from the provider JSON.","If only the async variant is implemented, route calls through the async path (async_transform_ocr_response).","Verify the model's provider resolves to the intended config class.","Use a built-in OCR provider with full response support."],"exampleFix":"# before: no response transform\nclass MyOCRConfig(BaseOCRConfig): ...\n\n# after\nclass MyOCRConfig(BaseOCRConfig):\n    def transform_ocr_response(self, model, raw_response, logging_obj, **kwargs):\n        body = raw_response.json()\n        return OCRResponse(text=body['content'], model=model, source='ocr')","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"def can_transform_ocr_response(config) -> bool:\n    base = BaseOCRConfig\n    return (type(config).transform_ocr_response is not base.transform_ocr_response\n            or type(config).async_transform_ocr_response is not base.async_transform_ocr_response)","tryCatchPattern":"try:\n    ocr_resp = config.transform_ocr_response(model, raw_response, logging_obj)\nexcept NotImplementedError:\n    ocr_resp = await config.async_transform_ocr_response(model, raw_response, logging_obj)  # async-only config","preventionTips":["Implement both sync and async response hooks, or clearly support only one and route accordingly.","Test the full OCR round trip per provider, not just request building.","Fail registration if a config implements request but not response transforms."],"tags":["ocr","not-implemented","response-parsing","provider-config"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}