BerriAI/litellm · error · Exception
Failed to fetch file
Error message
Failed to fetch file '{file_path}' via JSON endpoint: {e} What it means
Catch-all of the JSON fallback fetch: any non-401/403/404 failure while GETting /repository/files/<path>?ref=... is wrapped here with the original exception text appended. It is reached only after the raw endpoint returned 404, so infrastructure problems stack on top of whatever made the raw request miss.
Solutions
- Verify base_url ends with /api/v4 and the host is reachable
- Reproduce with curl against the JSON endpoint (the URL printed in the error)
- Retry transient 5xx/429/network errors with backoff
- Cache prompt files locally to ride out GitLab blips
Example fix
# before
content = client.get_file_content("prompts/greet.prompt")
# after: tolerate transient GitLab failures
for attempt in range(3):
try:
content = client.get_file_content("prompts/greet.prompt")
break
except Exception as e:
if attempt == 2 or "via JSON endpoint" not in str(e):
raise
time.sleep(2 ** attempt) Defensive patterns
Strategy: retry
Validate before calling
import socket
from urllib.parse import urlparse
def gitlab_host_reachable(base_url: str) -> bool:
host = urlparse(base_url).hostname or ""
try:
socket.getaddrinfo(host, 443)
return True
except socket.gaierror:
return False Try / catch
import time
def fetch_with_retry(client, path, attempts=3):
for i in range(attempts):
try:
return client.get_file_content(path)
except Exception as e:
msg = str(e)
retryable = "via JSON endpoint" in msg and any(
t in msg for t in ("timed out", "ConnectError", "500", "502", "503", "429")
)
if i == attempts - 1 or not retryable:
raise
time.sleep(2 ** i) Prevention
- Add DNS/reachability checks for the GitLab host to your readiness probe
- Bound retries and cache prompt content locally
- Monitor GitLab status pages for on-prem maintenance windows
When it happens
Trigger: Self-hosted GitLab outage or restart; base_url missing /api/v4; TLS/proxy failures; 5xx or 429 responses; DNS resolution failure; timeouts fetching large prompt files through the JSON API.
Common situations: On-prem GitLab maintenance windows; misrouted private networks; rate-limited automation loops; slow mirrors adding latency to the base64 JSON path.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- Failed to fetch file
- Failed to get repository info
- Failed to list files in
- Error listing files in
- Access denied to directory
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/1d3ff91e710a3a1d.
Report an issue: GitHub.
Appendix: 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 77b7c6c40c)