BerriAI/litellm · error · Exception

Failed to fetch file '{file_path}': {e}

Error message

Failed to fetch file '{file_path}': {e}

What it means

Raised by BitBucketClient.get_file when the BitBucket API returns an HTTP error status other than 404/403/401 (those have dedicated handling). The original exception is embedded in the message text. Typical causes are 400 (bad request from malformed path/params), 429 (rate limit), or 5xx (BitBucket outage). The underlying status code is only visible inside '{e}'.

Source

Thrown at litellm/integrations/bitbucket/bitbucket_client.py:116

                # For binary files or when content-type is not text, try to decode as base64
                try:
                    return base64.b64decode(response.content).decode("utf-8")
                except Exception:
                    return response.text

        except Exception as e:
            # Check if it's an HTTP error
            if hasattr(e, "response") and hasattr(e.response, "status_code"):
                if e.response.status_code == 404:
                    return None
                elif e.response.status_code == 403:
                    raise Exception(
                        f"Access denied to file '{file_path}'. Check your BitBucket permissions for workspace '{self.workspace}' and repository '{self.repository}'."
                    )
                elif e.response.status_code == 401:
                    raise Exception("Authentication failed. Check your BitBucket access token and permissions.")
                else:
                    raise Exception(f"Failed to fetch file '{file_path}': {e}")
            else:
                raise Exception(f"Error fetching file '{file_path}': {e}")

    def list_files(self, directory_path: str = "", file_extension: str = ".prompt") -> list[str]:
        """
        List files in a directory with a specific extension.

        Args:
            directory_path: Directory path in the repository (empty for root)
            file_extension: File extension to filter by (default: .prompt)

        Returns:
            List of file paths
        """
        safe_dir: Final = _sanitize_file_path(directory_path) if directory_path else ""
        url: Final = f"{self.base_url}/repositories/{self.workspace}/{self.repository}/src/{self.branch}/{safe_dir}"

        try:

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Inspect the embedded exception text in the message for the actual status code
  2. Add rate-limit handling/backoff around get_file; reduce parallel fetches
  3. If 5xx, retry after a delay or check https://status.atlassian.com for BitBucket incidents
  4. If 400, log the exact URL/path used and compare with a working curl request

Example fix

# before
for p in client.list_files():
    client.get_file(p)  # burst of requests -> 429 wrapped in generic error

# after
import time
for p in client.list_files():
    for attempt in range(3):
        try:
            client.get_file(p)
            break
        except Exception as e:
            if "429" in str(e) and attempt < 2:
                time.sleep(2 ** attempt)
            else:
                raise
Defensive patterns

Strategy: retry

Validate before calling

import httpx

def api_healthy(token: str) -> bool:
    try:
        r = httpx.get("https://api.bitbucket.org/2.0/hooks", auth=("x-token-auth", token), timeout=5)
        return r.status_code < 500
    except httpx.HTTPError:
        return False

Try / catch

import time

def get_file_with_retry(client, path: str, attempts: int = 3):
    for i in range(attempts):
        try:
            return client.get_file(path)
        except Exception as e:
            transient = any(s in str(e) for s in ("429", "500", "502", "503", "timeout"))
            if transient and i < attempts - 1:
                time.sleep(2 ** i)
                continue
            raise

Prevention

When it happens

Trigger: Rate limiting (429) during heavy prompt loading; BitBucket API 5xx incidents; 400 from malformed request paths; network timeouts surfacing as HTTP errors; unexpected redirects.

Common situations: Fetching many .prompt files in a loop (list_files + get_file) without backoff; BitBucket cloud maintenance windows; a path that survives sanitization but still produces a bad request.

Related errors


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