BerriAI/litellm · error · ValueError

contents of file are None

Error message

contents of file are None

What it means

When converting an OpenAI-style file upload into a Bedrock batch JSONL file, the transformation requires actual file content. If openai_file_content is None (no file supplied in the request), it raises ValueError('contents of file are None') before any parsing. It is a request-shape guard on the /v1/files path for bedrock batches.

Source

Thrown at litellm/llms/bedrock/files/transformation.py:1275

                headers=raw_response.headers,
            )
        return HttpxBinaryResponseContent(response=raw_response)


class BedrockJsonlFilesTransformation:
    """
    Transforms OpenAI /v1/files/* requests to Bedrock S3 file uploads for batch processing
    """

    def transform_openai_file_content_to_bedrock_file_content(
        self, openai_file_content: FileTypes | None = None
    ) -> tuple[str, str]:
        """
        Transforms OpenAI FileContentRequest to Bedrock S3 file format
        """

        if openai_file_content is None:
            raise ValueError("contents of file are None")
        # Read the content of the file
        file_content: Final = self._get_content_from_openai_file(openai_file_content)

        # Split into lines and parse each line as JSON
        openai_jsonl_content: Final = [json.loads(line) for line in file_content.splitlines() if line.strip()]
        bedrock_jsonl_content = self._transform_openai_jsonl_content_to_bedrock_jsonl_content(openai_jsonl_content)
        bedrock_jsonl_string: Final = "\n".join(json.dumps(item) for item in bedrock_jsonl_content)
        object_name: Final = self._get_s3_object_name(openai_jsonl_content=openai_jsonl_content)
        return bedrock_jsonl_string, object_name

    def _transform_openai_jsonl_content_to_bedrock_jsonl_content(
        self, openai_jsonl_content: Sequence[_OpenAIBatchRecord]
    ):
        """
        Delegate to the main BedrockFilesConfig transformation method
        """
        config: Final = BedrockFilesConfig()
        return config._transform_openai_jsonl_content_to_bedrock_jsonl_content(openai_jsonl_content)

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Include a non-empty JSONL file in the 'file' part of the multipart /v1/files request.
  2. Each non-blank line must be valid JSON (an OpenAI batch record) – fix malformed lines before upload.
  3. If calling the transformation directly, always pass FileTypes (bytes, file-like, or (filename, content) tuple), never None.

Example fix

# before
files = {"file": ("batch.jsonl", None)}  # -> ValueError
# after
files = {"file": ("batch.jsonl", jsonl_bytes, "application/json")}
Defensive patterns

Strategy: validation

Validate before calling

import json

def valid_batch_file(content: bytes | None) -> bool:
    if not content:
        return False
    lines = [l for l in content.decode("utf-8").splitlines() if l.strip()]
    if not lines:
        return False
    try:
        [json.loads(l) for l in lines]
        return True
    except json.JSONDecodeError:
        return False

Type guard

from typing import Any

def is_file_payload(v: Any) -> bool:
    return v is not None and (
        isinstance(v, (bytes, str)) or hasattr(v, "read") or isinstance(v, tuple)
    )

Prevention

When it happens

Trigger: POST /v1/files with purpose=... (batch) routed to Bedrock where the multipart 'file' field is missing, or calling transform_openai_file_content_to_bedrock_file_content programmatically with the default openai_file_content=None.

Common situations: Client SDK sends filename only without payload; a proxy in front of litellm strips the multipart body; misconfigured integration that builds the files payload from an empty variable.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/b041d9897a86bf99. Report an issue: GitHub.