BerriAI/litellm · error · ValueError
purpose is required
Error message
purpose is required
What it means
The Bedrock create-file handler requires a non-None 'purpose' field alongside 'file'; it determines the S3 object naming strategy (batch JSONL parsing vs generic managed name). data.get('purpose') returned None.
Source
Thrown at litellm/llms/bedrock/files/transformation.py:347
Get the complete S3 URL for the file upload request
"""
request_params: Final = merge_bedrock_aws_request_params(litellm_params, optional_params)
bucket_name = litellm_params.get("s3_bucket_name") or os.getenv("AWS_S3_BUCKET_NAME")
if not bucket_name:
raise ValueError(
"S3 bucket_name is required. Set 's3_bucket_name' in litellm_params or AWS_S3_BUCKET_NAME env var"
)
bucket_name, object_prefix = split_configured_cloud_bucket_name(bucket_name)
s3_region_name: Final = litellm_params.get("s3_region_name") or optional_params.get("s3_region_name")
aws_region_name: Final = s3_region_name or self._get_aws_region_name(request_params, model)
file_data: Final = data.get("file")
purpose: Final = data.get("purpose")
if file_data is None:
raise ValueError("file is required")
if purpose is None:
raise ValueError("purpose is required")
extracted_file_data: Final = extract_file_data(file_data)
object_name = self.get_object_name(extracted_file_data, purpose)
if object_prefix:
object_name = f"{object_prefix}/{object_name}"
encoded_object_name: Final = encode_s3_object_key_for_url(object_name)
# S3 endpoint URL format
s3_endpoint_url: Final = (
request_params.get("s3_endpoint_url") or f"https://s3.{aws_region_name}.amazonaws.com"
).rstrip("/")
return f"{s3_endpoint_url}/{bucket_name}/{encoded_object_name}"
def get_supported_openai_params(self, model: str) -> list[OpenAICreateFileRequestOptionalParams]:
return []
def map_openai_params(
self,View on GitHub (pinned to 6c2dcb801b)
Solutions
- Include purpose='batch' (or the supported value) as a form field in the multipart request.
- Verify field name casing/spelling is exactly 'purpose'.
- For batch use, ensure the file is valid JSONL so naming proceeds.
Example fix
# before
requests.post(url, files={"file": f})
# after
requests.post(url, files={"file": f}, data={"purpose": "batch"}) Defensive patterns
Strategy: validation
Validate before calling
assert data.get("purpose") is not None, "form field 'purpose' is required" Try / catch
try:
resp = litellm.create_file(file=f, purpose="batch")
except ValueError as e:
if "purpose is required" in str(e):
return HTTP 400
raise Prevention
- Send purpose together with the file part in the same multipart request.
- Validate the client form schema once, centrally, not ad hoc per endpoint.
When it happens
Trigger: Multipart upload with the file part but the 'purpose' form field omitted, or sent under a different field name (e.g. 'purposes') or inside JSON where form parsing ignores it.
Common situations: Clients forwarding only the file; form field name typos; OpenAI-compatible clients that assume purpose is optional.
Related errors
- file content is required
- file is required
- File data is required
- file_id is required in file_content_request
- file_id must be a managed LiteLLM S3 file id
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/3b8b34cdaca4e5ab.
Report an issue: GitHub.