{"record":{"id":"5e6c63a49f7edb8d","repo":"BerriAI/litellm","slug":"invalid-s3-uri-format-s3-uri","errorCode":null,"errorMessage":"Invalid S3 URI format: {s3_uri}","messagePattern":"Invalid S3 URI format: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/llms/bedrock/common_utils.py","lineNumber":1409,"sourceCode":"        if model.startswith(\"bedrock/\"):\n            return model[8:]  # Remove \"bedrock/\" prefix\n        return model\n\n    def parse_s3_uri(self, s3_uri: str) -> tuple:\n        \"\"\"\n        Parse S3 URI into bucket and key components.\n\n        Args:\n            s3_uri: S3 URI (e.g., \"s3://bucket/key/path\")\n\n        Returns:\n            Tuple of (bucket, key)\n\n        Raises:\n            ValueError: If URI format is invalid\n        \"\"\"\n        if not s3_uri.startswith(\"s3://\"):\n            raise ValueError(f\"Invalid S3 URI format: {s3_uri}\")\n\n        s3_parts: Final = s3_uri[5:].split(\"/\", 1)  # Remove \"s3://\" and split on first \"/\"\n        if len(s3_parts) != 2:\n            raise ValueError(f\"Invalid S3 URI format: {s3_uri}\")\n\n        return s3_parts[0], s3_parts[1]  # bucket, key\n\n    def extract_model_from_s3_file_path(self, s3_uri: str, optional_params: dict) -> str:\n        \"\"\"\n        Extract model ID from S3 file path.\n\n        The Bedrock file transformation creates S3 objects with the model name embedded:\n        Format: s3://bucket/litellm-bedrock-files-{model}-{uuid}.jsonl\n        \"\"\"\n        # Check if model is provided in optional_params first\n        if \"model\" in optional_params and optional_params[\"model\"]:\n            return self.get_bedrock_model_id_from_litellm_model(optional_params[\"model\"])\n","sourceCodeStart":1391,"sourceCodeEnd":1427,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/llms/bedrock/common_utils.py#L1391-L1427","documentation":"Raised by the Bedrock S3 URI parser when the supplied string does not start with the 's3://' scheme. LiteLLM requires canonical S3 URIs for Bedrock file transformations (document upload for converse APIs), and this is the first structural check. The same message is reused for a second failure where the remainder contains no '/' separator.","triggerScenarios":"Passing an http(s) URL, local file path, bare bucket name, or a typo'd scheme (e.g. 'S3://bucket/key' with uppercase) anywhere LiteLLM expects an s3_uri for Bedrock file handling; calling parse on a string like 's3://bucketonly' (no key) hits the sibling check at line 1413.","commonSituations":"Copying a file URL from the AWS console (which is https), user-supplied file references not validated upstream, or building the URI by string concatenation that drops the scheme.","solutions":["Normalize the URI to the form s3://<bucket>/<key> before passing it to LiteLLM","If the source is an AWS console link (https://s3.<region>.amazonaws.com/bucket/key), convert it to s3://bucket/key","Validate user-supplied URIs with a regex or urllib.parse before they reach the Bedrock path"],"exampleFix":"// before\nawait client.messages.create(model=..., files=[{\"file_data\": \"https://s3.us-east-1.amazonaws.com/mybucket/doc.json\"}])\n\n// after\nawait client.messages.create(model=..., files=[{\"file_data\": \"s3://mybucket/doc.json\"}])","handlingStrategy":"validation","validationCode":"import re\nS3_URI_RE = re.compile(r\"^s3://[^/]+/.+$\")\n\ndef is_valid_s3_uri(uri: str) -> bool:\n    return isinstance(uri, str) and bool(S3_URI_RE.match(uri))","typeGuard":"def is_s3_uri(value: str) -> bool:\n    return isinstance(value, str) and value.startswith(\"s3://\") and \"/\" in value[5:]","tryCatchPattern":"try:\n    bucket, key = parse_s3_uri(uri)\nexcept ValueError as e:\n    raise ValueError(f\"Bad file reference '{uri}': expected s3://bucket/key\") from e","preventionTips":["Validate file_data URIs against ^s3://[^/]+/.+$ before sending requests","Convert AWS console https URLs to s3:// form at ingest time","Centralize S3 URI construction in one helper so the scheme is never hand-typed"],"tags":["bedrock","s3","validation","uri"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}