cocoindex-io/cocoindex · error · ValueError
Cannot specify both an S3 URI and a separate key. Pass eithe
Error message
Cannot specify both an S3 URI and a separate key. Pass either get_object(client, 's3://bucket/key') or get_object(client, 'bucket', 'key').
What it means
get_object accepts either an S3 URI ('s3://bucket/key') or a separate bucket name plus key, but not both at once. Passing a URI as the first argument together with a key kwarg is ambiguous, so the function raises this ValueError.
Source
Thrown at python/cocoindex/connectors/amazon_s3/_source.py:218
Example::
import aiobotocore.session
from cocoindex.connectors import amazon_s3
session = aiobotocore.session.get_session()
async with session.create_client("s3") as client:
# Via S3 URI:
f = await amazon_s3.get_object(client, "s3://my-bucket/data/config.json")
data = await f.read()
# Via bucket name + key:
f = await amazon_s3.get_object(client, "my-bucket", "data/config.json")
data = await f.read()
"""
if bucket_name_or_uri.startswith("s3://"):
if key is not None:
raise ValueError(
"Cannot specify both an S3 URI and a separate key. "
"Pass either get_object(client, 's3://bucket/key') "
"or get_object(client, 'bucket', 'key')."
)
bucket_name, key = _parse_s3_uri(bucket_name_or_uri)
else:
bucket_name = bucket_name_or_uri
if key is None:
raise ValueError(
"key must be provided when bucket_name_or_uri is not an S3 URI."
)
return await _s3file_from_head(client, bucket_name, key)
async def read(client: AioBaseClient, uri: str, size: int = -1) -> bytes:
"""
Read object content directly from an S3 URI.
View on GitHub (pinned to e84aa99b32)
Solutions
- Remove the key argument and pass only the URI: get_object(client, 's3://bucket/key').
- Or drop the s3:// prefix from the first argument and pass bucket and key separately: get_object(client, 'bucket', 'key').
- If the first argument comes from config, normalize it: if it starts with 's3://', don't forward a key.
Example fix
// before f = await amazon_s3.get_object(client, "s3://my-bucket/data/config.json", "data/config.json") // after f = await amazon_s3.get_object(client, "s3://my-bucket/data/config.json")
Defensive patterns
Strategy: validation
Validate before calling
def get_object_once(client, bucket_or_uri, key=None):
if bucket_or_uri.startswith("s3://") and key is not None:
raise ValueError("pass either URI or (bucket, key), not both")
return amazon_s3.get_object(client, bucket_or_uri) if key is None else amazon_s3.get_object(client, bucket_or_uri, key) Try / catch
try:
f = await amazon_s3.get_object(client, uri, key)
except ValueError as e:
# fall back to URI-only form
f = await amazon_s3.get_object(client, uri) Prevention
- Pick one calling convention per codebase and stick to it.
- When refactoring between forms, grep call sites for leftover key arguments.
- Wrap the API in a small helper that accepts a single object descriptor.
When it happens
Trigger: Calling `amazon_s3.get_object(client, 's3://my-bucket/data/config.json', 'data/config.json')` or `get_object(client, 's3://bucket/key', key='key')` — first arg starts with s3:// and key is not None.
Common situations: Refactoring code from the two-argument form to the URI form (or vice versa) and leaving the old key argument in place; copying example code and editing only one parameter.
Related errors
- key must be provided when bucket_name_or_uri is not an S3 UR
- Invalid S3 URI {uri!r}: expected 's3://bucket/key'.
- expected None{loc}, got {type(value).__name__}
- expected {tp}{loc}, got {type(value).__name__}: {value!r}
- expected tuple{loc}, got {type(value).__name__}
AI-assisted analysis of cocoindex-io/cocoindex@e84aa99b32 (2026-09-08).
Data as JSON: /api/errors/8672169e61ccd2f8.
Report an issue: GitHub.