{"record":{"id":"d0efbfc8ae83b61a","repo":"BerriAI/litellm","slug":"file-data-is-required-d0efbf","errorCode":null,"errorMessage":"File data is required","messagePattern":"File data is required","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/llms/gemini/files/transformation.py","lineNumber":120,"sourceCode":"        return optional_params\n\n    def transform_create_file_request(\n        self,\n        model: str,\n        create_file_data: CreateFileRequest,\n        optional_params: dict,\n        litellm_params: dict,\n    ) -> dict:\n        \"\"\"\n        Transform the OpenAI-style file creation request into Gemini's format\n\n        Returns:\n            dict: Contains both request data and headers for the two-step upload\n        \"\"\"\n        # Extract the file information\n        file_data: Final = create_file_data.get(\"file\")\n        if file_data is None:\n            raise ValueError(\"File data is required\")\n\n        # Use the common utility function to extract file data\n        extracted_data: Final = extract_file_data(file_data)\n\n        # Get file size\n        file_size: Final = len(extracted_data[\"content\"])\n\n        # Step 1: Initial resumable upload request\n        headers: Final = {\n            \"X-Goog-Upload-Protocol\": \"resumable\",\n            \"X-Goog-Upload-Command\": \"start\",\n            \"X-Goog-Upload-Header-Content-Length\": str(file_size),\n            \"X-Goog-Upload-Header-Content-Type\": extracted_data[\"content_type\"],\n            \"Content-Type\": \"application/json\",\n        }\n        headers.update(extracted_data[\"headers\"])  # Add any custom headers\n\n        # Initial metadata request body","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/llms/gemini/files/transformation.py#L102-L138","documentation":"transform_create_file_request() takes the OpenAI-style create_file_data dict and extracts create_file_data['file']. If the key is absent (value None) it raises 'File data is required' — the two-step resumable upload protocol needs the raw bytes and filename from the file entry before it can compute content length and start the upload.","triggerScenarios":"Calling the file-creation transformation with a payload dict lacking the 'file' key, e.g. {'filename': 'a.png'} or an accidentally empty dict — typically when calling litellm.create_file without the file argument or with it under a different name.","commonSituations":"Migrating from OpenAI's files API where the parameter shape differs; passing a path string instead of a file object; kwargs built dynamically where the 'file' entry was never added because the upstream file handle was None.","solutions":["Pass the file argument: litellm.create_file(model='gemini/', file=open('data.pdf','rb'), purpose='user_data').","When building the payload programmatically, assert 'file' is present and non-None before invoking create_file.","Open the file in binary mode and keep the handle alive until the call returns."],"exampleFix":"# before\nlitellm.create_file(model=\"gemini/\", purpose=\"user_data\")  # no file -> ValueError\n\n# after\nwith open(\"report.pdf\", \"rb\") as f:\n    litellm.create_file(model=\"gemini/\", file=f, purpose=\"user_data\")","handlingStrategy":"validation","validationCode":"def validate_create_file_args(file) -> None:\n    if file is None:\n        raise ValueError(\"create_file requires an open binary file object\")\n    if not hasattr(file, \"read\"):\n        raise TypeError(\"file must be a file-like object, not a path string\")","typeGuard":"def is_file_like(obj: object) -> bool:\n    return hasattr(obj, \"read\") and hasattr(obj, \"close\")","tryCatchPattern":"try:\n    litellm.create_file(model=\"gemini/\", file=f, purpose=\"user_data\")\nexcept ValueError as e:\n    if \"File data is required\" in str(e):\n        raise RuntimeError(\"Open the file and pass it via file=...\") from e\n    raise","preventionTips":["Always call create_file with keyword args including file= as an open binary handle.","Check upstream handles for None (failed opens) before building the request.","Wrap file acquisition in a context manager so the handle is guaranteed valid at call time."],"tags":["gemini","files","validation","request-validation"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}