{"record":{"id":"0e86fac210740ae3","repo":"BerriAI/litellm","slug":"file-id-or-file-data-is-required","errorCode":null,"errorMessage":"file_id or file_data is required","messagePattern":"file_id or file_data is required","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/llms/hosted_vllm/chat/transformation.py","lineNumber":146,"sourceCode":"            mime_type = _parse_mime_type(file_data)\n            if mime_type and mime_type.startswith(\"video/\"):\n                return True\n        elif file_id:\n            mime_type = _get_image_mime_type_from_url(file_id)\n            if mime_type and mime_type.startswith(\"video/\"):\n                return True\n        return False\n\n    def _convert_file_to_video_url(self, content_item: ChatCompletionFileObject) -> ChatCompletionVideoObject:\n        file: Final = content_item.get(\"file\", {})\n        file_id: Final = file.get(\"file_id\")\n        file_data: Final = file.get(\"file_data\")\n\n        if file_id:\n            return ChatCompletionVideoObject(type=\"video_url\", video_url=ChatCompletionVideoUrlObject(url=file_id))\n        elif file_data:\n            return ChatCompletionVideoObject(type=\"video_url\", video_url=ChatCompletionVideoUrlObject(url=file_data))\n        raise ValueError(\"file_id or file_data is required\")\n\n    @overload\n    def _transform_messages(\n        self, messages: list[AllMessageValues], model: str, is_async: Literal[True]\n    ) -> Coroutine[Any, Any, list[AllMessageValues]]: ...\n\n    @overload\n    def _transform_messages(\n        self,\n        messages: list[AllMessageValues],\n        model: str,\n        is_async: Literal[False] = False,\n    ) -> list[AllMessageValues]: ...\n\n    def _transform_messages(\n        self, messages: list[AllMessageValues], model: str, is_async: bool = False\n    ) -> list[AllMessageValues] | Coroutine[Any, Any, list[AllMessageValues]]:\n        \"\"\"","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/llms/hosted_vllm/chat/transformation.py#L128-L164","documentation":"Raised by HostedVLLM's _convert_file_to_video_url when a chat message content item of type 'file' has neither file_id nor file_data inside its file object. The transformation tries to convert file content into a video_url object; with an empty file dict there is nothing to put in the URL, so it fails fast with ValueError.","triggerScenarios":"Sending a message content part like {'type':'file','file':{}} (or a file dict with only unrelated keys such as 'filename') to a hosted_vllm model. Only file_id or file_data are recognized; anything else falls through to the raise.","commonSituations":"Building multimodal messages generically and passing a file part with a local path or bytes under a non-standard key; migrating from OpenAI client code that used different file-object keys; upstream schema change where the producer stopped populating file_id/file_data.","solutions":["Populate one of the recognized keys: {'type':'file','file':{'file_id':'<url-or-id>'}} or {'type':'file','file':{'file_data':'data:video/mp4;base64,...'}}.","If you intended an inline video, base64-encode it into a data URL and use file_data.","If you intended a URL, put it in file_id (the code uses it directly as the video_url).","Validate message content parts before calling litellm if they come from user input or another service."],"exampleFix":"# before\nmessages=[{'role':'user','content':[\n    {'type':'text','text':'describe this'},\n    {'type':'file','file':{'path':'/tmp/clip.mp4'}},\n]}]  # raises ValueError: file_id or file_data is required\n\n# after\nmessages=[{'role':'user','content':[\n    {'type':'text','text':'describe this'},\n    {'type':'file','file':{'file_data':'data:video/mp4;base64,'+b64}},\n]}]\n","handlingStrategy":"validation","validationCode":"def is_valid_file_part(part: dict) -> bool:\n    if part.get(\"type\") != \"file\":\n        return True\n    f = part.get(\"file\") or {}\n    return bool(f.get(\"file_id\") or f.get(\"file_data\"))\n\ndef validate_message_content(messages: list[dict]) -> None:\n    for m in messages:\n        content = m.get(\"content\")\n        if isinstance(content, list):\n            for part in content:\n                if not is_valid_file_part(part):\n                    raise ValueError(f\"file part missing file_id/file_data: {part}\")","typeGuard":"def has_file_payload(part: dict) -> bool:\n    \"\"\"Narrows a chat content part to one HostedVLLM can convert to video_url.\"\"\"\n    f = part.get(\"file\") or {}\n    return isinstance(f, dict) and (isinstance(f.get(\"file_id\"), str) or isinstance(f.get(\"file_data\"), str))","tryCatchPattern":null,"preventionTips":["Construct multimodal parts through a small builder function that only emits file_id/file_data keys.","Validate incoming message payloads (external APIs/users) against the expected content-part schema before forwarding to litellm."],"tags":["hosted-vllm","multimodal","validation","video","message-format"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}