BerriAI/litellm · error · RuntimeError
Mavvrik FOCUS destination: failed to get signed URL ({resp.s
Error message
Mavvrik FOCUS destination: failed to get signed URL ({resp.status_code}): {resp.text[:200]} What it means
Before uploading, the destination GETs the Mavvrik upload-url endpoint (params name/type=metrics/datetime) to obtain a GCS signed URL. Any status >= 400 raises RuntimeError embedding the status and truncated body. Unlike registration, this is not cached — it happens per delivery date.
Source
Thrown at litellm/integrations/focus/destinations/mavvrik_destination.py:148
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,
)
if resp.status_code >= 400:
raise RuntimeError(
f"Mavvrik FOCUS destination: failed to get signed URL ({resp.status_code}): {resp.text[:200]}"
)
signed_url: Final = resp.json().get("url")
if not signed_url:
raise RuntimeError(f"Mavvrik FOCUS destination: response missing 'url' field: {resp.json()}")
_validate_gcs_url(signed_url, "signed URL")
verbose_logger.debug("Mavvrik FOCUS destination: got signed URL for date %s", date_str)
return signed_url
async def _upload_to_gcs(self, signed_url: str, content: bytes) -> None:
"""Upload gzip-compressed CSV to GCS via chunked resumable upload.
The full CSV is gzip-compressed first, then uploaded in _GCS_CHUNK_SIZE
chunks using the GCS resumable upload protocol. GCS assembles the chunks
server-side into a single complete object — the bucket receives one file
regardless of how many chunks were sent.
Intermediate chunks: Content-Range: bytes X-Y/* → expect 308View on GitHub (pinned to 6c2dcb801b)
Solutions
- Inspect the embedded status: 403 → grant upload permission to the key; 429 → back off and retry with jitter; 5xx → retry after a delay.
- Verify the date passed (time_window) is sane and the connection is registered first.
- Wrap delivery in a retry with exponential backoff for 429/5xx, since signed-URL fetch is idempotent.
- Contact Mavvrik support with the body snippet if 4xx persists.
Defensive patterns
Strategy: retry
Try / catch
import asyncio
for attempt in range(4):
try:
await mavvrik_dest.deliver(content=csv, time_window=tw, filename="f.csv")
break
except RuntimeError as e:
if "failed to get signed URL" not in str(e) or attempt == 3:
raise
if any(s in str(e) for s in ("(401)", "(403)", "(404)")):
raise
await asyncio.sleep(2 ** attempt + 1) # backoff for 429/5xx Prevention
- Back off on 429/5xx — the signed-URL fetch is safe to retry and is not cached.
- Ensure registration succeeds before the first delivery attempt so upload-url calls carry valid state.
When it happens
Trigger: Calling deliver() when the API key lacks permission for the upload-url endpoint (403), the connection_id/date combination is unknown (404), Mavvrik rate-limits or errors (429/5xx), or the query params are rejected (400).
Common situations: Key valid for registration but scoped away from uploads; quota exhaustion on repeated exports; Mavvrik-side incidents; clock skew making the datetime param look out of range.
Related errors
- Mavvrik FOCUS destination: register failed ({resp.status_cod
- Mavvrik FOCUS destination: GCS session init failed ({init_re
- Mavvrik FOCUS destination: {label} must be HTTPS, got scheme
- Mavvrik FOCUS destination: response missing 'url' field: {re
- Mavvrik FOCUS destination: GCS session init missing Location
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/540448e3b6aad836.
Report an issue: GitHub.