BerriAI/litellm · error · ValueError
bucket_name must be provided for GCS destination
Error message
bucket_name must be provided for GCS destination
What it means
FocusGCSDestination's constructor reads bucket_name from its config dict and immediately raises if falsy before calling super().__init__ on GCSBucketBase. This is the destination-class-level guard; it normally fires only when the class is instantiated directly, bypassing the factory (the factory already enforces FOCUS_GCS_BUCKET_NAME).
Source
Thrown at litellm/integrations/focus/destinations/gcs_destination.py:29
encode_gcs_object_name_for_url,
)
from .base import FocusDestination, FocusTimeWindow
class FocusGCSDestination(GCSBucketBase, FocusDestination):
"""Upload serialized Focus exports to GCS using the GCS JSON API."""
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 GCS destination")
super().__init__(bucket_name=bucket_name)
service_account_json: Final = config.get("service_account_json")
if service_account_json is not None:
self.path_service_account_json = service_account_json
self.prefix = prefix.rstrip("/")
async def deliver(
self,
*,
content: bytes,
time_window: FocusTimeWindow,
filename: str,
) -> None:
object_name: Final = self._build_object_key(time_window=time_window, filename=filename)
headers: Final = await self.construct_request_headers(service_account_json=self.path_service_account_json)
headers["Content-Type"] = "application/octet-stream"
encoded_name: Final = encode_gcs_object_name_for_url(object_name)
url: Final = (View on GitHub (pinned to 6c2dcb801b)
Solutions
- Include bucket_name (bare bucket name, no gs:// scheme) in the config dict passed to FocusGCSDestination.
- Prefer using the destination factory, which also resolves env vars, instead of constructing the class directly.
- Validate the config dict keys before instantiation.
Example fix
# before
dest = FocusGCSDestination(prefix="focus", config={"bucket": "my-bucket"})
# after
dest = FocusGCSDestination(prefix="focus", config={"bucket_name": "my-bucket"}) Defensive patterns
Strategy: validation
Validate before calling
cfg = config or {}
if not cfg.get("bucket_name"):
raise ValueError("FocusGCSDestination requires config['bucket_name'] (bare name, no gs:// scheme)") Type guard
def is_valid_gcs_dest_config(config: dict | None) -> bool:
return bool(config) and isinstance(config.get("bucket_name"), str) and bool(config["bucket_name"].strip()) and not config["bucket_name"].startswith("gs://") Try / catch
try:
dest = FocusGCSDestination(prefix=prefix, config=config)
except ValueError as e:
if "bucket_name" in str(e):
raise ConfigError("GCS destination misconfigured") from e
raise Prevention
- Prefer the destination factory over direct construction so env fallbacks apply.
- Keep a config schema (pydantic/JSON schema) for destination dicts to catch key-name drift early.
When it happens
Trigger: Instantiating FocusGCSDestination(prefix=..., config={...}) directly with config missing 'bucket_name' or config=None; passing bucket under a different key like 'bucket' or 'gs://bucket' as a full URI instead of a bare name.
Common situations: Custom wiring that constructs the destination class instead of going through the factory; config dicts assembled from YAML where the key name drifted; passing the full gs:// URI rather than the bare bucket name.
Related errors
- FOCUS_GCS_BUCKET_NAME must be provided for GCS exports
- FOCUS_S3_BUCKET_NAME must be provided for S3 exports
- VANTAGE_API_KEY must be provided for Vantage exports
- VANTAGE_INTEGRATION_TOKEN must be provided for Vantage expor
- MAVVRIK_API_ENDPOINT must be an HTTPS URL
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/970276fd0e904237.
Report an issue: GitHub.