cocoindex-io/cocoindex · error · ValueError

key must be provided when bucket_name_or_uri is not an S3 UR

Error message

key must be provided when bucket_name_or_uri is not an S3 URI.

What it means

When the first argument to get_object is not an s3:// URI it is treated as a bare bucket name, so a separate key is mandatory. If key is None in that branch, the function cannot know which object to fetch and raises this ValueError.

Source

Thrown at python/cocoindex/connectors/amazon_s3/_source.py:227

            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.

    This is a convenience shortcut that skips the metadata fetch
    (``head_object``) performed by :func:`get_object`.

    Args:
        client: An aiobotocore S3 client.
        uri: An S3 URI (``s3://bucket/key``).
        size: Number of bytes to read. If -1 (default), read the entire object.

    Returns:

View on GitHub (pinned to e84aa99b32)

Solutions

  1. Pass the key: get_object(client, 'my-bucket', 'data/config.json').
  2. Or use the full URI form: get_object(client, 's3://my-bucket/data/config.json').
  3. Guard dynamic key values: raise early in your own code if key is None before calling get_object.

Example fix

// before
f = await amazon_s3.get_object(client, "my-bucket")

// after
f = await amazon_s3.get_object(client, "my-bucket", "data/config.json")
Defensive patterns

Strategy: validation

Validate before calling

assert key is not None, "key required when passing a bare bucket name"
f = await amazon_s3.get_object(client, bucket, key)

Try / catch

try:
    f = await amazon_s3.get_object(client, bucket, key)
except ValueError as e:
    logger.error("missing key for bucket %s: %s", bucket, e)
    raise

Prevention

When it happens

Trigger: Calling get_object(client, 'my-bucket') with no key, or get_object(client, 'my-bucket', key=None) where the first argument lacks the s3:// prefix.

Common situations: Forgetting the key when switching from URI form to bucket form; key computed dynamically (e.g. from a template) and evaluating to None due to an upstream bug.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of cocoindex-io/cocoindex@e84aa99b32 (2026-09-08). Data as JSON: /api/errors/0e7a52b2a5b54499. Report an issue: GitHub.