BerriAI/litellm · error · ValueError

bucket_name must be provided for S3 destination

Error message

bucket_name must be provided for S3 destination

What it means

FocusS3Destination.__init__ raises ValueError when the destination config dict has no non-empty 'bucket_name' key. The S3 destination needs a target bucket to construct object keys for FOCUS exports; without it the destination cannot be constructed safely.

Source

Thrown at litellm/integrations/focus/destinations/s3_destination.py:26

import boto3

from .base import FocusDestination, FocusTimeWindow


class FocusS3Destination(FocusDestination):
    """Handles uploading serialized exports to S3 buckets."""

    def __init__(
        self,
        *,
        prefix: str,
        config: dict[str, Any] | None = None,
    ) -> None:
        config = config or {}
        bucket_name: Final = config.get("bucket_name")
        if not bucket_name:
            raise ValueError("bucket_name must be provided for S3 destination")
        self.bucket_name = bucket_name
        self.prefix = prefix.rstrip("/")
        self.config = config

    async def deliver(
        self,
        *,
        content: bytes,
        time_window: FocusTimeWindow,
        filename: str,
    ) -> None:
        object_key: Final = self._build_object_key(time_window=time_window, filename=filename)
        await asyncio.to_thread(self._upload, content, object_key)

    def _build_object_key(self, *, time_window: FocusTimeWindow, filename: str) -> str:
        start_utc: Final = time_window.start_time.astimezone(timezone.utc)
        date_component: Final = f"date={start_utc.strftime('%Y-%m-%d')}"
        parts: Final = [self.prefix, date_component]

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Pass bucket_name in the destination config: config={'bucket_name': 'my-focus-export-bucket', ...}.
  2. Check for typos/whitespace in the key and ensure the value is a non-empty string.
  3. Verify the bucket exists and the credentials in the same config have s3:PutObject rights.

Example fix

// before
FocusS3Destination(prefix="focus", config={"bucket": "my-bucket"})

// after
FocusS3Destination(prefix="focus", config={"bucket_name": "my-bucket"})
Defensive patterns

Strategy: validation

Validate before calling

cfg = dest_config or {}
if not cfg.get("bucket_name"):
    raise ValueError("destination_config['bucket_name'] is required for the S3 FOCUS destination")
dest = FocusS3Destination(prefix=prefix, config=cfg)

Type guard

def is_valid_s3_config(cfg: dict) -> bool:
    return isinstance(cfg, dict) and isinstance(cfg.get("bucket_name"), str) and len(cfg["bucket_name"].strip()) > 0

Prevention

When it happens

Trigger: Constructing FocusS3Destination(prefix=..., config={}) or config={'bucket_name': ''} / {'bucket_name': None} — e.g. the FOCUS destination_config from env/settings omitted bucket_name.

Common situations: Typo in the config key ('bucket' vs 'bucket_name'); passing the settings dict of a different destination type; reading bucket from an env var that is unset.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/8dbd3420e405e61f. Report an issue: GitHub.