{"record":{"id":"a09872fc31959051","repo":"BerriAI/litellm","slug":"file-id-must-include-a-cloud-storage-object-name","errorCode":null,"errorMessage":"file_id must include a cloud storage object name","messagePattern":"file_id must include a cloud storage object name","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/litellm_core_utils/cloud_storage_security.py","lineNumber":147,"sourceCode":"    if isinstance(value, str):\n        return value.strip().lower() in {\"1\", \"true\", \"yes\", \"on\"}\n    return False\n\n\ndef validate_managed_cloud_file_id(\n    file_id: str,\n    scheme: str,\n    configured_bucket_name: str,\n    allowed_object_prefixes: Sequence[str],\n    allow_legacy_cloud_file_ids: bool = False,\n) -> tuple[str, str]:\n    decoded_file_id: Final = unquote(file_id)\n    if not decoded_file_id.startswith(scheme):\n        raise ValueError(f\"file_id must be a {scheme} URI\")\n\n    full_path: Final = decoded_file_id[len(scheme) :]\n    if \"/\" not in full_path:\n        raise ValueError(\"file_id must include a cloud storage object name\")\n\n    bucket_name, object_name = full_path.split(\"/\", 1)\n    configured_bucket, configured_prefix = split_configured_cloud_bucket_name(configured_bucket_name)\n    if bucket_name != configured_bucket:\n        raise ValueError(\"file_id bucket does not match the configured storage bucket\")\n\n    _validate_cloud_object_path(object_name)\n    allowed_prefixes = tuple(allowed_object_prefixes)\n    if configured_prefix:\n        allowed_prefixes = tuple(f\"{configured_prefix.rstrip('/')}/{prefix}\" for prefix in allowed_prefixes)\n\n    if object_name.startswith(allowed_prefixes):\n        return bucket_name, object_name\n\n    if allow_legacy_cloud_file_ids:\n        if configured_prefix and not object_name.startswith(f\"{configured_prefix.rstrip('/')}/\"):\n            raise ValueError(\"file_id object does not match the configured storage prefix\")\n        return bucket_name, object_name","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/litellm_core_utils/cloud_storage_security.py#L129-L165","documentation":"In validate_managed_cloud_file_id, after stripping the scheme the remainder must contain at least one '/', because the managed format is '<scheme><bucket>/<object>'. This error means the id decoded to just a bucket (or bare token) with no object name — there is nothing to fetch and the split into bucket/object would be meaningless.","triggerScenarios":"file_id like 'gs://my-bucket' (scheme and bucket but no '/object'), or a value whose '/' was lost to encoding such as 'gs%3A%2F%2Fmy-bucket' decoding oddly. full_path = decoded[len(scheme):] contains no '/' and the guard fires.","commonSituations":"Truncating stored URIs at the first '/' during ETL; string-formatting bugs that drop the object portion (f\"gs://{bucket}\" instead of f\"gs://{bucket}/{obj}\"); users assuming the bucket alone identifies a file.","solutions":["Use the full managed URI including object name: 'gs://my-bucket/path/to/object.json'.","Audit where the id was produced — f-string or URL parsing that dropped everything after the bucket — and fix the producer.","When generating ids yourself, follow scheme + bucket + '/' + object and run a quick '/'-presence check before sending."],"exampleFix":"# before\nfile_id = f\"gs://{bucket}\"                 # missing object part\n\n# after\nfile_id = f\"gs://{bucket}/{object_name}\"   # e.g. gs://my-bucket/litellm/x.json","handlingStrategy":"type-guard","validationCode":"from urllib.parse import unquote\n\ndef has_object_component(file_id: str, scheme: str = \"gs://\") -> bool:\n    return \"/\" in unquote(file_id)[len(scheme):]","typeGuard":"def is_full_managed_uri(v: object, scheme: str = \"gs://\") -> bool:\n    if not isinstance(v, str):\n        return False\n    rest = unquote(v)[len(scheme):]\n    return \"/\" in rest and bool(rest.split(\"/\", 1)[1])","tryCatchPattern":"try:\n    validate_managed_cloud_file_id(fid, scheme, bucket, prefixes)\nexcept ValueError as e:\n    if \"object name\" in str(e):\n        fid = f\"{fid.rstrip('/')}/{default_object}\"  # or ask caller for the full URI\n    raise","preventionTips":["Always build ids as f\"{scheme}{bucket}/{object}\" — both parts mandatory.","Round-trip test id generation/parsing in CI.","Validate ids after any ETL that touches their string form."],"tags":["file-upload","cloud-storage","file-id","validation"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}