BerriAI/litellm · error · ValueError

file_id or file_data is required

Error message

file_id or file_data is required

What it means

When transforming chat messages for hosted vLLM, a message part of type 'file' is converted into a 'video_url' part by _convert_file_to_video_url(). The nested file object must contain either file_id (used directly as the video URL) or file_data (base64/data payload used as the URL). If both are missing or empty, a ValueError is raised during request transformation, before any HTTP call.

Solutions

  1. Provide file_id as a fetchable URL: {'type':'file','file':{'file_id':'https://example.com/clip.mp4'}}
  2. Or provide inline data: {'type':'file','file':{'file_data':'data:video/mp4;base64,<...>'}}
  3. If you already have a URL, skip the file part and use {'type':'video_url','video_url':{'url':'https://...'}} directly
  4. Validate content parts before calling litellm.completion so the failure is caught client-side

Example fix

# before
content = [{"type": "file", "file": {"filename": "clip.mp4"}}]
litellm.completion(model="hosted_vllm/Qwen/Qwen2-VL-7B", messages=[{"role": "user", "content": content}])

# after
content = [{
    "type": "file",
    "file": {"file_id": "https://example.com/clip.mp4"},
}]
litellm.completion(model="hosted_vllm/Qwen/Qwen2-VL-7B", messages=[{"role": "user", "content": content}])
Defensive patterns

Strategy: validation

Validate before calling

def valid_file_parts(messages: list[dict]) -> bool:
    for m in messages:
        for part in m.get("content") or []:
            if isinstance(part, dict) and part.get("type") == "file":
                f = part.get("file") or {}
                if not (f.get("file_id") or f.get("file_data")):
                    return False
    return True

assert valid_file_parts(messages), "every file part needs file_id or file_data"

Type guard

from typing import Any

def is_valid_file_part(part: Any) -> bool:
    if not isinstance(part, dict) or part.get("type") != "file":
        return True  # not a file part — nothing to check
    f = part.get("file")
    return isinstance(f, dict) and bool(f.get("file_id") or f.get("file_data"))

Prevention

When it happens

Trigger: Sending a message like {'role':'user','content':[{'type':'file','file':{}}]} or {'type':'file','file':{'filename':'clip.mp4'}} (keys other than file_id/file_data) to a hosted_vllm model. The raise happens in _transform_messages, so any completion call with such a part triggers it deterministically.

Common situations: Building multimodal content programmatically where optional fields end up empty; assuming OpenAI's broader file-part schema (which permits other keys) is accepted; putting a local file path under an unsupported key like 'path' or 'filename'.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/0e86fac210740ae3. Report an issue: GitHub.

Appendix: source

Thrown at litellm/llms/hosted_vllm/chat/transformation.py:146

            mime_type = _parse_mime_type(file_data)
            if mime_type and mime_type.startswith("video/"):
                return True
        elif file_id:
            mime_type = _get_image_mime_type_from_url(file_id)
            if mime_type and mime_type.startswith("video/"):
                return True
        return False

    def _convert_file_to_video_url(self, content_item: ChatCompletionFileObject) -> ChatCompletionVideoObject:
        file: Final = content_item.get("file", {})
        file_id: Final = file.get("file_id")
        file_data: Final = file.get("file_data")

        if file_id:
            return ChatCompletionVideoObject(type="video_url", video_url=ChatCompletionVideoUrlObject(url=file_id))
        elif file_data:
            return ChatCompletionVideoObject(type="video_url", video_url=ChatCompletionVideoUrlObject(url=file_data))
        raise ValueError("file_id or file_data is required")

    @overload
    def _transform_messages(
        self, messages: list[AllMessageValues], model: str, is_async: Literal[True]
    ) -> Coroutine[Any, Any, list[AllMessageValues]]: ...

    @overload
    def _transform_messages(
        self,
        messages: list[AllMessageValues],
        model: str,
        is_async: Literal[False] = False,
    ) -> list[AllMessageValues]: ...

    def _transform_messages(
        self, messages: list[AllMessageValues], model: str, is_async: bool = False
    ) -> list[AllMessageValues] | Coroutine[Any, Any, list[AllMessageValues]]:
        """

View on GitHub (pinned to 77b7c6c40c)