{"record":{"id":"4ed1f95c9fd47fae","repo":"BerriAI/litellm","slug":"ocr-file-input-does-not-accept-bare-str-values-pa","errorCode":null,"errorMessage":"OCR file input does not accept bare str values. Pass bytes, a pathlib.Path, or a file-like object. To OCR a local file from a path, call open(path, 'rb') yourself.","messagePattern":"OCR file input does not accept bare str values\\. Pass bytes, a pathlib\\.Path, or a file-like object\\. To OCR a local file from a path, call open\\(path, 'rb'\\) yourself\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/ocr/main.py","lineNumber":512,"sourceCode":"    file_input: Final = document.get(\"file\")\n    if file_input is None:\n        raise ValueError(\n            \"document with type='file' must include a 'file' field containing \"\n            \"a pathlib.Path, file-like object, or bytes\"\n        )\n\n    file_bytes: bytes\n    mime_type: str = \"application/octet-stream\"\n    file_name: str | None = None\n\n    if isinstance(file_input, str):\n        # Bare strings are rejected here. The OCR ``document`` accepts a\n        # ``{\"type\": \"file\", \"file\": <value>}`` shape, and when this helper\n        # runs in a proxy request handler ``<value>`` is attacker-controlled.\n        # Opening it as a path is an arbitrary local file read on the proxy\n        # host, which is then base64-encoded and forwarded to the OCR\n        # provider — an exfiltration primitive.\n        raise ValueError(\n            \"OCR file input does not accept bare str values. Pass bytes, \"\n            \"a pathlib.Path, or a file-like object. To OCR a local file \"\n            \"from a path, call open(path, 'rb') yourself.\"\n        )\n    if isinstance(file_input, os.PathLike):\n        # os.PathLike (pathlib.Path and custom __fspath__ classes) is a\n        # Python-level type that HTTP form values can't fabricate.\n        file_path: Final = str(file_input)\n        if not os.path.isfile(file_path):\n            raise FileNotFoundError(f\"File not found: {file_path}\")\n        mime_type = get_mime_type(file_path)\n        file_name = os.path.basename(file_path)\n        with open(file_path, \"rb\") as f:\n            file_bytes = f.read()\n    elif isinstance(file_input, bytes):\n        file_bytes = file_input\n    elif isinstance(file_input, IOBase) or hasattr(file_input, \"read\"):\n        if hasattr(file_input, \"name\"):","sourceCodeStart":494,"sourceCodeEnd":530,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/ocr/main.py#L494-L530","documentation":"Security guard in the OCR file helper: file was supplied as a bare string. Because proxy request handlers pass user-controlled values, opening a str path would be an arbitrary-file-read/exfiltration primitive, so strings are refused and callers must pass bytes/Path/file objects themselves.","triggerScenarios":"Thrown at litellm/ocr/main.py:512 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Do not pass a raw path string; open the file yourself and pass bytes, a Path, or a file-like object."],"exampleFix":"file=open('/path/to/file.pdf','rb')  # then pass this instead of '/path/to/file.pdf'","handlingStrategy":"validation","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-14T00:17:10.932Z"}