BerriAI/litellm · error · ValueError

MAVVRIK_API_KEY must be provided for Mavvrik FOCUS destinati

Error message

MAVVRIK_API_KEY must be provided for Mavvrik FOCUS destination (set MAVVRIK_API_KEY env var or pass in destination_config)

What it means

FocusMavvrikDestination.__init__ requires api_key from the config dict (the factory normally populates it from MAVVRIK_API_KEY). Unlike the factory path, this constructor does not read env vars itself — if you bypass the factory and pass no api_key, it raises immediately with guidance to set the env var or destination_config entry.

Source

Thrown at litellm/integrations/focus/destinations/mavvrik_destination.py:67

        )


class FocusMavvrikDestination(FocusDestination):
    """Upload FOCUS CSV exports to Mavvrik via GCS signed URL."""

    def __init__(
        self,
        *,
        prefix: str,
        config: dict[str, Any] | None = None,
    ) -> None:
        config = config or {}
        api_key: Final = config.get("api_key")
        api_endpoint: Final = config.get("api_endpoint")
        connection_id: Final = config.get("connection_id")

        if not api_key:
            raise ValueError(
                "MAVVRIK_API_KEY must be provided for Mavvrik FOCUS destination "
                "(set MAVVRIK_API_KEY env var or pass in destination_config)"
            )
        if not api_endpoint:
            raise ValueError(
                "MAVVRIK_API_ENDPOINT must be provided for Mavvrik FOCUS destination "
                "(set MAVVRIK_API_ENDPOINT env var or pass in destination_config)"
            )
        if not connection_id:
            raise ValueError(
                "MAVVRIK_CONNECTION_ID must be provided for Mavvrik FOCUS destination "
                "(set MAVVRIK_CONNECTION_ID env var or pass in destination_config)"
            )

        _validate_api_endpoint(api_endpoint)

        self.api_key = api_key
        self.api_endpoint = api_endpoint.rstrip("/")

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Set MAVVRIK_API_KEY in the environment (and let the factory pass it through), or put api_key in the destination config dict.
  2. Verify the value is non-empty before creating the destination.
  3. If constructing the class directly, mirror the factory: config['api_key'] = os.environ['MAVVRIK_API_KEY'].

Example fix

# before
dest = FocusMavvrikDestination(prefix="focus", config={"api_endpoint": ep, "connection_id": cid})

# after
dest = FocusMavvrikDestination(
    prefix="focus",
    config={
        "api_key": os.environ["MAVVRIK_API_KEY"],
        "api_endpoint": ep,
        "connection_id": cid,
    },
)
Defensive patterns

Strategy: validation

Validate before calling

import os

if not (os.getenv("MAVVRIK_API_KEY") or config.get("api_key")):
    raise SystemExit("MAVVRIK_API_KEY missing: set it or pass api_key in destination config")

Try / catch

try:
    dest = FocusMavvrikDestination(prefix=p, config=cfg)
except ValueError as e:
    if "MAVVRIK_API_KEY" in str(e):
        log_config_error("mavvrik", missing=["api_key"])
    raise

Prevention

When it happens

Trigger: Constructing FocusMavvrikDestination(prefix=..., config={...}) directly with no api_key key (config=None or {}), or via the factory with MAVVRIK_API_KEY unset and no override.

Common situations: Secret not mounted in k8s; env var name typo (MAVRIK_API_KEY); direct class instantiation in custom wiring; empty-string value from secrets templating.

Related errors


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