{"record":{"id":"f721d0c3827d0aab","repo":"BerriAI/litellm","slug":"mavvrik-focus-destination-register-failed-resp","errorCode":null,"errorMessage":"Mavvrik FOCUS destination: register failed ({resp.status_code}): {resp.text[:200]}","messagePattern":"Mavvrik FOCUS destination: register failed \\((.+?)\\): (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"litellm/integrations/focus/destinations/mavvrik_destination.py","lineNumber":128,"sourceCode":"        Returns None if the connector was already registered (cached).\n        \"\"\"\n        if self._registered:\n            return None\n        resp: Final = await self._http.client.request(\n            method=\"POST\",\n            url=self._agent_url,\n            headers=self._auth_headers,\n            json={\"name\": self.connection_id},\n            timeout=30.0,\n        )\n        if resp.status_code == 410:\n            self._registered = False\n            raise RuntimeError(\n                \"Mavvrik FOCUS destination: connector is disconnected (410). \"\n                \"Re-enable the connection in the Mavvrik dashboard.\"\n            )\n        if resp.status_code >= 400:\n            raise RuntimeError(f\"Mavvrik FOCUS destination: register failed ({resp.status_code}): {resp.text[:200]}\")\n        self._registered = True\n        metrics_marker: Final = resp.json().get(\"metricsMarker\", 0)\n        verbose_logger.debug(\n            \"Mavvrik FOCUS destination: connector registered (metricsMarker=%s)\",\n            metrics_marker,\n        )\n        return metrics_marker\n\n    async def _get_signed_url(self, date_str: str) -> str:\n        \"\"\"GET upload-url endpoint → GCS signed URL for the given date.\"\"\"\n        params: Final = {\"name\": date_str, \"type\": \"metrics\", \"datetime\": date_str}\n        resp: Final = await self._http.client.request(\n            method=\"GET\",\n            url=self._upload_url_endpoint,\n            headers=self._auth_headers,\n            params=params,\n            timeout=30.0,\n        )","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/integrations/focus/destinations/mavvrik_destination.py#L110-L146","documentation":"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.","triggerScenarios":"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.","commonSituations":"Revoked or rotated API keys; endpoint missing the tenant ID segment; Mavvrik incident; connection_id containing characters the API rejects (400 validation).","solutions":["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.","Retry on 5xx — registration is retried on the next deliver() since _registered stays False.","Confirm the three env vars match a working connection by exercising the register endpoint manually with curl.","If persistent, contact Mavvrik support with the status code and body snippet."],"exampleFix":"# defensive wrapper\ntry:\n    await mavvrik_dest.deliver(content=csv, time_window=tw, filename=\"f.csv\")\nexcept RuntimeError as e:\n    if \"register failed\" in str(e):\n        alert_ops(f\"Mavvrik registration error: {e}\")\n    raise","handlingStrategy":"retry","validationCode":"# cheap pre-flight: credentials present and endpoint reachable\nimport httpx, os\nassert os.environ[\"MAVVRIK_API_KEY\"], \"api key required\"\nr = httpx.get(os.environ[\"MAVVRIK_API_ENDPOINT\"].rstrip(\"/\") + \"/health\", timeout=5)\nassert r.status_code < 500, \"Mavvrik API unhealthy\"","typeGuard":null,"tryCatchPattern":"import asyncio\n\nfor attempt in range(3):\n    try:\n        await mavvrik_dest.deliver(content=csv, time_window=tw, filename=\"f.csv\")\n        break\n    except RuntimeError as e:\n        if \"register failed\" not in str(e) or attempt == 2:\n            raise\n        if any(s in str(e) for s in (\"(401)\", \"(403)\")):\n            raise  # auth: retrying won't help\n        await asyncio.sleep(2 ** attempt)","preventionTips":["Distinguish embedded status codes in the message: retry only 5xx/429, fix config on 4xx.","Rotate API keys through a controlled two-phase process (add new, switch, revoke old) to avoid 401 windows."],"tags":["focus","mavvrik","network","http","auth"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}