From 1f38a63e3fe6400ae75fe549a79fec0ef006de34 Mon Sep 17 00:00:00 2001 From: Ishaan Jaffer Date: Mon, 23 Mar 2026 11:56:27 -0700 Subject: [PATCH] fix: NotRequired for file_size TypedDict field; defensive seek(0) before file_data --- litellm/proxy/openai_files_endpoints/files_endpoints.py | 4 ++++ litellm/types/utils.py | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/litellm/proxy/openai_files_endpoints/files_endpoints.py b/litellm/proxy/openai_files_endpoints/files_endpoints.py index 9ebab733279..9369f9b256b 100644 --- a/litellm/proxy/openai_files_endpoints/files_endpoints.py +++ b/litellm/proxy/openai_files_endpoints/files_endpoints.py @@ -446,6 +446,10 @@ async def create_file( # noqa: PLR0915 # Pass file.file (the underlying SpooledTemporaryFile / BytesIO) rather than # reading all bytes into memory — the IO object is fully compatible with # FileTypes and lets downstream providers stream the upload. + # Ensure pointer is at 0 before any code reads from file.file, so that + # subsequent seek-based operations (file_size, JSONL sniff, upload) start + # from the beginning of the file regardless of prior reads. + file.file.seek(0) file_data = (file.filename, file.file, file.content_type) ## check if model is a loadbalanced model diff --git a/litellm/types/utils.py b/litellm/types/utils.py index b191276c465..d4df4538aff 100644 --- a/litellm/types/utils.py +++ b/litellm/types/utils.py @@ -41,7 +41,7 @@ from pydantic import ( field_validator, model_validator, ) -from typing_extensions import Required, TypedDict +from typing_extensions import NotRequired, Required, TypedDict from litellm._uuid import uuid from litellm.types.llms.base import ( @@ -3494,7 +3494,7 @@ class ExtractedFileData(TypedDict): content: Union[bytes, "IO[bytes]"] content_type: Optional[str] headers: Mapping[str, str] - file_size: Optional[int] + file_size: NotRequired[Optional[int]] class SpecialEnums(Enum):