{"record":{"id":"2ae7c3b4442840c5","repo":"BerriAI/litellm","slug":"error-parsing-file-upload-response-e","errorCode":null,"errorMessage":"Error parsing file upload response: {e}","messagePattern":"Error parsing file upload response: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/llms/gemini/files/transformation.py","lineNumber":192,"sourceCode":"                id=response_object[\"uri\"],  # Gemini uses URI as identifier\n                bytes=int(response_object[\"sizeBytes\"]),  # Gemini doesn't return file size\n                created_at=int(\n                    time.mktime(\n                        time.strptime(\n                            response_object[\"createTime\"].replace(\"Z\", \"+00:00\"),\n                            \"%Y-%m-%dT%H:%M:%S.%f%z\",\n                        )\n                    )\n                ),\n                filename=response_object[\"displayName\"],\n                object=\"file\",\n                purpose=\"user_data\",  # Default to assistants as that's the main use case\n                status=\"uploaded\",\n                status_details=None,\n            )\n        except Exception as e:\n            verbose_logger.exception(\"Error parsing file upload response: %s\", e)\n            raise ValueError(f\"Error parsing file upload response: {e}\")\n\n    def transform_retrieve_file_request(\n        self,\n        file_id: str,\n        optional_params: dict,\n        litellm_params: dict,\n    ) -> tuple[str, dict]:\n        \"\"\"\n        Get the URL to retrieve a file from Google AI Studio.\n\n        Endpoint:\n        GET https://generativelanguage.googleapis.com/v1beta/{name=files/*}\n\n        The URL should look like:\n        https://generativelanguage.googleapis.com/v1beta/files/{file_id}?key=API_KEY\n\n        We expect file_id to be just the file identifier (e.g., files/abc123 or abc123)\n        as returned by the upload response. (If it's a full URL, extract the file name.)","sourceCodeStart":174,"sourceCodeEnd":210,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/llms/gemini/files/transformation.py#L174-L210","documentation":"After the Gemini resumable upload completes, litellm parses the final response JSON (name, displayName, createTime timestamps) into an OpenAI-style file object inside a try/except. Any failure while parsing — missing keys, unexpected timestamp formats, or a non-JSON body — is logged via verbose_logger.exception and re-raised as ValueError('Error parsing file upload response: ...') with the parsing exception appended.","triggerScenarios":"The upload endpoint returns a 2xx whose body is not the expected File object JSON (e.g. an HTML page from an intercepting proxy, a truncated body), or Google changes a field format such as createTime so datetime.strptime fails.","commonSituations":"Corporate proxies or gateways that replace response bodies; partial reads on dropped connections; schema drift between litellm's parser version and the live Files API.","solutions":["Enable verbose logging (litellm.verbose = True or set LITELLM_LOG=DEBUG) — the logged exception names the exact parse failure and field.","Retry the upload: truncated/proxied responses are frequently one-off; resumable upload will start a new session.","Upgrade litellm to the latest release so the Files response parser matches Google's current schema."],"exampleFix":"# before\nfile_obj = litellm.create_file(model=\"gemini/\", file=f)\n# parse failure crashes the app\n\n# after\nimport litellm\ntry:\n    file_obj = litellm.create_file(model=\"gemini/\", file=f)\nexcept ValueError as e:\n    if \"Error parsing file upload response\" in str(e):\n        file_obj = litellm.create_file(model=\"gemini/\", file=f)  # retry once\n    else:\n        raise","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"def upload_gemini_file(f, attempts: int = 2):\n    for i in range(attempts):\n        try:\n            return litellm.create_file(model=\"gemini/\", file=f, purpose=\"user_data\")\n        except ValueError as e:\n            if \"Error parsing file upload response\" in str(e):\n                f.seek(0)  # reset handle for a clean retry\n                continue\n            raise\n    raise RuntimeError(\"Gemini file upload failed to parse response after retries\")","preventionTips":["Seek(0) the file handle before retrying uploads — consumed streams cause second failures.","Enable litellm verbose logging in upload paths; the parse exception is logged with full detail.","Watch for intermediaries (proxies, WAFs) that rewrite response bodies, and bypass them for googleapis.com."],"tags":["gemini","files","response-parsing","upload"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}