{"record":{"id":"42d11425a2583ad2","repo":"BerriAI/litellm","slug":"file-content-is-required","errorCode":null,"errorMessage":"file content is required","messagePattern":"file content is required","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/llms/bedrock/files/transformation.py","lineNumber":300,"sourceCode":"        named as: litellm-bedrock-files/{model}/{uuid}\n        \"\"\"\n        _model = openai_jsonl_content[0].get(\"body\", {}).get(\"model\", \"\")\n        # Remove bedrock/ prefix if present\n        _model = _model.removeprefix(\"bedrock/\")\n\n        safe_model: Final = sanitize_cloud_object_component(_model.replace(\":\", \"-\"), fallback=\"model\")\n\n        object_name: Final = f\"{BEDROCK_MANAGED_S3_BATCH_PREFIX}{safe_model}-{uuid.uuid4()}.jsonl\"\n        return object_name\n\n    def get_object_name(self, extracted_file_data: ExtractedFileData, purpose: str) -> str:\n        \"\"\"\n        Get the object name for the request\n        \"\"\"\n        extracted_file_data_content: Final = extracted_file_data.get(\"content\")\n\n        if extracted_file_data_content is None:\n            raise ValueError(\"file content is required\")\n\n        if purpose == \"batch\":\n            ## 1. If jsonl, check if there's a model name\n            file_content: Final = self._get_content_from_openai_file(extracted_file_data_content)\n\n            # Split into lines and parse each line as JSON\n            openai_jsonl_content: Final = [json.loads(line) for line in file_content.splitlines() if line.strip()]\n            if len(openai_jsonl_content) > 0:\n                return self._get_s3_object_name_from_batch_jsonl(openai_jsonl_content)\n\n        ## 2. If not jsonl, store under a server-generated managed object name\n        filename: Final = extracted_file_data.get(\"filename\")\n        return build_managed_cloud_object_name(\n            prefix=BEDROCK_MANAGED_S3_UPLOAD_PREFIX,\n            filename=filename,\n            fallback_filename=\"file\",\n        )\n","sourceCodeStart":282,"sourceCodeEnd":318,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/llms/bedrock/files/transformation.py#L282-L318","documentation":"BedrockJsonlFilesTransformation.get_object_name() needs the uploaded file's bytes (via extracted_file_data['content']) both to name the object and, for batch purpose, to parse each JSONL line and derive the model-specific object name. Missing content means the extraction step failed or the caller bypassed it.","triggerScenarios":"Calling create-file (upload) where extracted_file_data carries metadata only — content is None because the multipart file body was not read, or a custom File storage integration passed an already-consumed file object.","commonSituations":"Custom integrations constructing ExtractedFileData manually and omitting 'content'; a FastAPI/Starlette upload handler reading the stream before litellm does; tests with stub file objects lacking bytes.","solutions":["Ensure the actual file bytes are attached as extracted_file_data['content'] (bytes) before upload.","Use litellm's standard file upload flow rather than constructing ExtractedFileData by hand.","If a framework consumed the stream, reset via await file.seek(0) before passing it on."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"def has_content(extracted_file_data: dict) -> bool:\n    return extracted_file_data.get(\"content\") is not None","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use litellm's standard upload flow; don't hand-build ExtractedFileData.","In web frameworks, seek(0) the upload before passing it to litellm."],"tags":["bedrock","files","upload","validation"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}