{"record":{"id":"ee5d3f3e8c6dfe35","repo":"BerriAI/litellm","slug":"no-choices-in-deepseek-ocr-response","errorCode":null,"errorMessage":"No choices in DeepSeek OCR response","messagePattern":"No choices in DeepSeek OCR response","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/llms/vertex_ai/ocr/deepseek_transformation.py","lineNumber":270,"sourceCode":"        Args:\n            model: Model name\n            raw_response: Raw HTTP response from Vertex AI\n            logging_obj: Logging object\n            **kwargs: Additional arguments\n\n        Returns:\n            OCRResponse in standard format\n        \"\"\"\n        verbose_logger.debug(\"Vertex AI DeepSeek OCR transform_ocr_response called\")\n        verbose_logger.debug(\"Raw response: %s\", raw_response.text)\n\n        try:\n            response_json: Final = raw_response.json()\n\n            # Extract OCR content from provider response\n            choices: Final = response_json.get(\"choices\", [])\n            if not choices:\n                raise ValueError(\"No choices in DeepSeek OCR response\")\n\n            message: Final = choices[0].get(\"message\", {})\n            content: Final = message.get(\"content\", \"\")\n\n            if not content:\n                raise ValueError(\"No content in DeepSeek OCR response\")\n\n            # Try to parse content as JSON (OCR result might be JSON string)\n            ocr_data = None\n            try:\n                # If content is a JSON string, parse it\n                if isinstance(content, str) and content.strip().startswith(\"{\"):\n                    ocr_data = json.loads(content)\n                elif isinstance(content, dict):\n                    ocr_data = content\n                else:\n                    # If content is markdown text, create a single page with the markdown\n                    ocr_data = {","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/llms/vertex_ai/ocr/deepseek_transformation.py#L252-L288","documentation":"ValueError raised when the DeepSeek OCR response parses as JSON but contains no 'choices' array. The transformer expects a chat-style body ({'choices': [{'message': {'content': ...}}]}); a 200 response with any other shape fails here. The raw response text is debug-logged just before the raise, so verbose logging captures the actual body.","triggerScenarios":"Vertex returns 200 with an error or status object instead of choices; a schema change in the DeepSeek OCR model output; a proxy rewrites or strips the choices field.","commonSituations":"Model or endpoint version drift on Vertex; misrouted model name hitting a different endpoint; gateways that re-envelope responses.","solutions":["Enable verbose/debug logging to capture the 'Raw response: %s' line and see the actual body","Confirm the model name routes to the DeepSeek OCR endpoint on Vertex","If a proxy sits in front, verify it passes the Vertex body through unchanged","Update litellm to the latest version in case the provider schema changed and litellm adapted"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"import litellm\nlitellm.verbose = True  # the transformer debug-logs the raw body before raising\n\ntry:\n    resp = litellm.ocr(model=model, document=doc)\nexcept ValueError as e:\n    if 'No choices' in str(e):\n        log.error('deepseek ocr: body without choices; check verbose logs for the raw response')\n        resp = litellm.ocr(model=model, document=doc)  # single retry if transient\n    else:\n        raise","preventionTips":["Run with verbose logging in non-prod to capture raw OCR bodies","Pin known-good litellm and Vertex model versions","Route OCR traffic directly to Vertex, not through re-envelope proxies"],"tags":["vertex-ai","ocr","response-schema","empty-response"],"backgroundTag":"unexpected-response-schema","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}