{"record":{"id":"507ffdb6b7fe6ad9","repo":"BerriAI/litellm","slug":"batch-upload-file-handle-must-be-seekable-got-a-n","errorCode":null,"errorMessage":"Batch upload file handle must be seekable; got a non-seekable stream. Pass bytes, a path, or a seekable handle.","messagePattern":"Batch upload file handle must be seekable; got a non-seekable stream\\. Pass bytes, a path, or a seekable handle\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/llms/vertex_ai/files/transformation.py","lineNumber":597,"sourceCode":"        return\n\n    if isinstance(content, str):\n        yield from _iter_stripped_lines(io.StringIO(content))\n        return\n\n    if isinstance(content, PathLike):\n        with open(str(content), \"rb\") as handle:\n            yield from _iter_stripped_lines(handle)\n        return\n\n    if hasattr(content, \"read\"):\n        # The handle is read twice per upload (first-row probe for the GCS\n        # object name, then the body stream), so it must rewind to 0. A\n        # non-seekable handle would silently resume mid-stream and drop the\n        # already-consumed first row, so reject it loudly instead.\n        seek: Final = getattr(content, \"seek\", None)\n        if seek is None:\n            raise ValueError(\n                \"Batch upload file handle must be seekable; got a non-seekable \"\n                \"stream. Pass bytes, a path, or a seekable handle.\"\n            )\n        try:\n            seek(0)\n        except (OSError, ValueError) as e:\n            raise ValueError(\n                \"Batch upload file handle must be seekable so it can be re-read \"\n                \"for the GCS object name and the upload body.\"\n            ) from e\n        yield from _iter_stripped_lines(content)\n        return\n\n    raise ValueError(\"Unsupported file content type\")\n\n\ndef _iter_openai_jsonl_entries(\n    openai_file_content: FileTypes,","sourceCodeStart":579,"sourceCodeEnd":615,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/llms/vertex_ai/files/transformation.py#L579-L615","documentation":"Batch file iteration guard: the supplied file object has a read() method but no seek(), and the upload reads the handle twice (first-row probe then body), so a non-seekable stream would silently drop data and is rejected loudly.","triggerScenarios":"Triggered when the batch upload file handle is a non-seekable stream; pass bytes, a path, or a seekable handle.","commonSituations":"See trigger scenarios.","solutions":["Pass bytes, a file path, or a seekable file handle for the batch upload."],"exampleFix":"file=open(\"batch.jsonl\",\"rb\")  # seekable handle","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-14T05:17:10.506Z"}