BerriAI/litellm · error · ValueError
file_id must be a managed LiteLLM S3 file id
Error message
file_id must be a managed LiteLLM S3 file id
What it means
validate_managed_cloud_file_id accepts only ids that decode to LiteLLM-managed ids (base64url payloads with the LITELM_MANAGED_FILE_ID_PREFIX) or literal 's3://' URIs; anything else is rejected to prevent unvalidated file-id injection into S3 key resolution.
Source
Thrown at litellm/llms/bedrock/files/transformation.py:175
Resolve a Bedrock file id to its S3 URI.
Accepts either a base64-encoded LiteLLM unified file id (whose decoded
form carries `llm_output_file_id,s3://...`) or a direct `s3://` URI.
"""
try:
padded: Final = file_id + "=" * (-len(file_id) % 4)
decoded: Final = base64.urlsafe_b64decode(padded).decode()
if decoded.startswith(SpecialEnums.LITELM_MANAGED_FILE_ID_PREFIX.value):
if "llm_output_file_id," in decoded:
return decoded.split("llm_output_file_id,")[1].split(";")[0]
except Exception:
pass
if file_id.startswith("s3://"):
return file_id
raise ValueError("file_id must be a managed LiteLLM S3 file id")
def get_configured_s3_bucket_name(litellm_params: Mapping[str, object]) -> str:
"""
Resolve the server-configured S3 bucket for Bedrock file operations.
Only trusts the immutable server-side credential snapshot or the
environment; never a request-supplied param, since the bucket is what
`validate_managed_cloud_file_id` checks file ids against.
"""
trusted_model_credentials: Final = litellm_params.get("_litellm_internal_model_credentials")
bucket_name: str | None = None
if isinstance(trusted_model_credentials, MappingProxyType):
snapshot: Final[dict[str, object]] = {}
snapshot.update(trusted_model_credentials) # any-ok: untyped snapshot
bucket_name = _TrustedS3ModelCredentials.model_validate(snapshot).s3_bucket_name
bucket_name = bucket_name or os.getenv("AWS_S3_BUCKET_NAME")
if not bucket_name:View on GitHub (pinned to 6c2dcb801b)
Solutions
- Use the id returned by litellm's create-file endpoint for Bedrock (an s3:// URI or a managed LiteLLM id).
- If you own the object, pass the full 's3://bucket/key' URI directly.
- Re-upload the file through litellm to obtain a valid managed id.
Example fix
# before handler.file_content(FileContentRequest(file_id="file-1a2b3c")) # after handler.file_content(FileContentRequest(file_id="s3://my-bucket/bedrock-managed-batch/model-uuid.jsonl"))
Defensive patterns
Strategy: type-guard
Validate before calling
import base64
from litellm.constants import SpecialEnums # prefix enum
def is_managed_or_s3_id(file_id: str) -> bool:
if file_id.startswith("s3://"):
return True
try:
padded = file_id + "=" * (-len(file_id) % 4)
return base64.urlsafe_b64decode(padded).decode().startswith(
SpecialEnums.LITELM_MANAGED_FILE_ID_PREFIX.value
)
except Exception:
return False Type guard
def is_usable_bedrock_file_id(file_id: str) -> bool:
return file_id.startswith("s3://") or is_managed_or_s3_id(file_id) Try / catch
try:
content = handler.file_content(FileContentRequest(file_id=fid))
except ValueError as e:
if "managed LiteLLM S3 file id" in str(e):
raise BadUserInput(fid) # 400 to client
raise Prevention
- Persist the id litellm's create-file returns, not upstream provider ids.
- Namespace stored ids by provider to avoid OpenAI/Bedrock mixups.
When it happens
Trigger: Passing a raw OpenAI file id (e.g. 'file-abc123') or arbitrary string as file_id to Bedrock file content/operations instead of the managed id returned by litellm's file create, and not an s3:// URI.
Common situations: Migrating from OpenAI to Bedrock-backed files and reusing OpenAI ids; client apps storing provider-agnostic ids; passing an id after the managed-prefix format changed between litellm versions.
Related errors
- file_id is required in file_content_request
- file content is required
- file is required
- purpose is required
- contents of file are None
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/e6491c27d10e8129.
Report an issue: GitHub.