{"record":{"id":"e473e98588d76530","repo":"BerriAI/litellm","slug":"document-type-file-is-not-supported-through-the","errorCode":null,"errorMessage":"document type 'file' is not supported through the JSON API. To upload a local file, use multipart/form-data with a 'file' field. For JSON requests, use 'document_url' or 'image_url' document types.","messagePattern":"document type 'file' is not supported through the JSON API\\. To upload a local file, use multipart/form-data with a 'file' field\\. For JSON requests, use 'document_url' or 'image_url' document types\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/proxy/ocr_endpoints/endpoints.py","lineNumber":171,"sourceCode":"\n    try:\n        data: Final = orjson.loads(body)\n    except orjson.JSONDecodeError as e:\n        raise ValueError(\n            f\"Invalid JSON in request body: {e}. \"\n            \"Ensure the request body is valid JSON with Content-Type: application/json, \"\n            \"or use multipart/form-data for file uploads.\"\n        )\n\n    # Security: reject type=\"file\" documents received via JSON.\n    # The \"file\" document type is designed for local SDK usage where the\n    # caller and the process share a filesystem.  In the proxy context the\n    # caller is remote, so allowing a file-path string would let an\n    # authenticated user read arbitrary files from the server's filesystem.\n    # File uploads must go through multipart/form-data instead.\n    doc: Final = data.get(\"document\") if isinstance(data, dict) else None\n    if isinstance(doc, dict) and doc.get(\"type\") == \"file\":\n        raise ValueError(\n            \"document type 'file' is not supported through the JSON API. \"\n            \"To upload a local file, use multipart/form-data with a 'file' field. \"\n            \"For JSON requests, use 'document_url' or 'image_url' document types.\"\n        )\n\n    # Security: reject provider-native file IDs (e.g. reducto://) received via\n    # JSON. These IDs are not scoped to the LiteLLM proxy user/key, so an\n    # authenticated user who obtains another user's file ID could submit it\n    # here and receive the OCR result using the proxy's shared provider\n    # credentials. Force callers to upload fresh content per request via\n    # multipart/form-data or an inline base64 data URI, both of which produce\n    # a server-mediated upload bound to the current request.\n    if isinstance(doc, dict):\n        for url_field in (\"document_url\", \"image_url\"):\n            url_value = doc.get(url_field)\n            if isinstance(url_value, str) and url_value.startswith(\"reducto://\"):\n                raise ValueError(\n                    \"reducto:// file IDs are not accepted through the proxy \"","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/ocr_endpoints/endpoints.py#L153-L189","documentation":"Error \"document type 'file' is not supported through the JSON API. To upload a local file, use multipart/form-data with a 'file' field. For JSON requests, use 'document_url' or 'image_url' document types.\" thrown in BerriAI/litellm.","triggerScenarios":"Thrown at litellm/proxy/ocr_endpoints/endpoints.py:171 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Use multipart/form-data with a 'file' field for local files, or use 'document_url'/'image_url' document types for JSON requests."],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}