BerriAI/litellm · error · RuntimeError

Mavvrik FOCUS destination: register failed ({resp.status_cod

Error message

Mavvrik FOCUS destination: register failed ({resp.status_code}): {resp.text[:200]}

What it means

During connector registration, any response status >= 400 other than 410 raises RuntimeError with the status code and first 200 chars of the body. Because it's an f-string, the real message carries the concrete failure — typical causes are 401/403 bad API key, 404 wrong endpoint/tenant path, and 5xx Mavvrik outages.

Source

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

        Returns None if the connector was already registered (cached).
        """
        if self._registered:
            return None
        resp: Final = await self._http.client.request(
            method="POST",
            url=self._agent_url,
            headers=self._auth_headers,
            json={"name": self.connection_id},
            timeout=30.0,
        )
        if resp.status_code == 410:
            self._registered = False
            raise RuntimeError(
                "Mavvrik FOCUS destination: connector is disconnected (410). "
                "Re-enable the connection in the Mavvrik dashboard."
            )
        if resp.status_code >= 400:
            raise RuntimeError(f"Mavvrik FOCUS destination: register failed ({resp.status_code}): {resp.text[:200]}")
        self._registered = True
        metrics_marker: Final = resp.json().get("metricsMarker", 0)
        verbose_logger.debug(
            "Mavvrik FOCUS destination: connector registered (metricsMarker=%s)",
            metrics_marker,
        )
        return metrics_marker

    async def _get_signed_url(self, date_str: str) -> str:
        """GET upload-url endpoint → GCS signed URL for the given date."""
        params: Final = {"name": date_str, "type": "metrics", "datetime": date_str}
        resp: Final = await self._http.client.request(
            method="GET",
            url=self._upload_url_endpoint,
            headers=self._auth_headers,
            params=params,
            timeout=30.0,
        )

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Read the embedded status/body: 401/403 → regenerate the API key in Mavvrik and update env; 404 → check api_endpoint includes the tenant path; 400 → check connection_id format.
  2. Retry on 5xx — registration is retried on the next deliver() since _registered stays False.
  3. Confirm the three env vars match a working connection by exercising the register endpoint manually with curl.
  4. If persistent, contact Mavvrik support with the status code and body snippet.

Example fix

# defensive wrapper
try:
    await mavvrik_dest.deliver(content=csv, time_window=tw, filename="f.csv")
except RuntimeError as e:
    if "register failed" in str(e):
        alert_ops(f"Mavvrik registration error: {e}")
    raise
Defensive patterns

Strategy: retry

Validate before calling

# cheap pre-flight: credentials present and endpoint reachable
import httpx, os
assert os.environ["MAVVRIK_API_KEY"], "api key required"
r = httpx.get(os.environ["MAVVRIK_API_ENDPOINT"].rstrip("/") + "/health", timeout=5)
assert r.status_code < 500, "Mavvrik API unhealthy"

Try / catch

import asyncio

for attempt in range(3):
    try:
        await mavvrik_dest.deliver(content=csv, time_window=tw, filename="f.csv")
        break
    except RuntimeError as e:
        if "register failed" not in str(e) or attempt == 2:
            raise
        if any(s in str(e) for s in ("(401)", "(403)")):
            raise  # auth: retrying won't help
        await asyncio.sleep(2 ** attempt)

Prevention

When it happens

Trigger: First deliver() call when the MAVVRIK_API_KEY is invalid (401), the api_endpoint tenant path is wrong (404), the Mavvrik API is down (5xx), or a request exceeds the 30s timeout path returning an error status.

Common situations: Revoked or rotated API keys; endpoint missing the tenant ID segment; Mavvrik incident; connection_id containing characters the API rejects (400 validation).

Related errors


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