BerriAI/litellm · error · Exception

Failed to fetch file '{file_path}' via JSON endpoint: {e}

Error message

Failed to fetch file '{file_path}' via JSON endpoint: {e}

What it means

Raised by GitLabClient.get_file_content when fetching a file via the GitLab repository files JSON endpoint fails with an error other than 404 (returns None), 403, or 401. The original exception (typically httpx.HTTPStatusError or a network error) is stringified into the message. This is the catch-all for 5xx responses, timeouts, DNS failures, and malformed base_url values.

Source

Thrown at litellm/integrations/gitlab/gitlab_client.py:181

            content: Final = data.get("content")
            encoding: Final = data.get("encoding", "")
            if content and encoding == "base64":
                try:
                    return base64.b64decode(content).decode("utf-8")
                except Exception:
                    return base64.b64decode(content).decode("utf-8", errors="replace")
            return content
        except Exception as e:
            status: Final = getattr(getattr(e, "response", None), "status_code", None)
            if status == 404:
                return None
            if status == 403:
                raise Exception(
                    f"Access denied to file '{file_path}'. Check your GitLab permissions for project '{self.project}'."
                )
            if status == 401:
                raise Exception("Authentication failed. Check your GitLab token and auth_method.")
            raise Exception(f"Failed to fetch file '{file_path}' via JSON endpoint: {e}")

    def list_files(
        self,
        directory_path: str = "",
        file_extension: str = ".prompt",
        recursive: bool = False,
        *,
        ref: str | None = None,
    ) -> list[str]:
        """
        List files in a directory with a specific extension using the repository tree API.

        Args:
            directory_path: Directory path in the repository (empty for repo root)
            file_extension: File extension to filter by (default: .prompt)
            recursive: If True, traverses subdirectories
            ref: Optional override (tag/branch/SHA). Defaults to self.ref.

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Inspect the wrapped exception text {e} to identify the real HTTP status or network error
  2. If it is a 5xx or timeout, retry after a delay or check the GitLab instance health
  3. Verify base_url (should be like https://gitlab.com/api/v4) and that the project identifier 'group/project' is correct
  4. Check for proxies/SSL interception between the host and GitLab
  5. If 429 rate limiting, reduce load_all_prompts() frequency or add caching

Example fix

// before
content = client.get_file_content('prompts/foo.prompt')

// after - surface status and retry transient failures
import time
for attempt in range(3):
    try:
        content = client.get_file_content('prompts/foo.prompt')
        break
    except Exception as e:
        if attempt == 2 or '429' not in str(e) and '5' not in str(e)[:50]:
            raise
        time.sleep(2 ** attempt)
Defensive patterns

Strategy: retry

Validate before calling

import httpx

def gitlab_reachable(base_url: str) -> bool:
    try:
        r = httpx.get(f"{base_url}/version", timeout=5)
        return r.status_code == 200
    except httpx.HTTPError:
        return False

Try / catch

try:
    content = client.get_file_content(path, ref=ref)
except Exception as e:
    msg = str(e)
    if any(code in msg for code in ("429", "500", "502", "503", "timed out")):
        # transient: retry with backoff
        raise RetryableError(msg) from e
    raise

Prevention

When it happens

Trigger: Calling get_file_content() (directly or via GitLabPromptManager prompt loading) when GitLab returns 500/502/503, when base_url is unreachable or misconfigured (wrong host, proxy interference), when the project path is URL-encoded incorrectly, or when httpx raises a connection/timeout error that has no .response attribute.

Common situations: Self-hosted GitLab instance down or restarting; corporate proxy blocking the request; base_url pointing to an API path that doesn't exist; rate limiting returning 429; typo in project slug producing unexpected error pages instead of clean 404s.

Related errors


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