BerriAI/litellm · error · Exception
Error fetching file
Error message
Error fetching file '{file_path}': {e} What it means
get_file_content wraps any exception that has no HTTP response attached — i.e., a transport-level failure: DNS resolution failure, connection refused/reset, TLS certificate verification error, proxy failures, or an unexpected decoding bug. The original exception text is appended verbatim, which distinguishes it from the HTTP-status variants (293-295).
Solutions
- Verify basic reachability: curl https://api.bitbucket.org/2.0 from the same container/host
- Configure the proxy via HTTPS_PROXY/HTTP_PROXY (and NO_PROXY for internal hosts) in the process env
- For TLS interception, trust the CA bundle: mount the corp CA and set SSL_CERT_FILE / REQUESTS_CA_BUNDLE for the httpx handler
- Pin a stable DNS/resolver in the pod spec (dnsPolicy) if resolution is flaky
Example fix
// before: pod has no egress -> 'Error fetching file ... [Errno -2] Name or service not known' // after export HTTPS_PROXY="http://proxy.corp.internal:3128" export SSL_CERT_FILE="/etc/ssl/certs/corp-ca-bundle.crt" python -m myapp # BitBucketClient now reaches api.bitbucket.org
Defensive patterns
Strategy: retry
Validate before calling
import socket, urllib.request
host = "api.bitbucket.org"
try:
socket.getaddrinfo(host, 443)
except socket.gaierror:
raise RuntimeError(f"cannot resolve {host}; fix DNS/egress before using BitBucketClient")
# optional reachability probe
try:
urllib.request.urlopen(f"https://{host}/2.0", timeout=5)
except Exception as e:
raise RuntimeError(f"no route to {host}: {e}") Try / catch
import random, time
for attempt in range(3):
try:
content = client.get_file_content(path)
break
except Exception as e:
if "Error fetching file" in str(e) and attempt < 2: # transport-level only
time.sleep(2 ** attempt + random.random())
continue
raise Prevention
- Verify egress/DNS from the exact container the client runs in (curl the API)
- Configure HTTPS_PROXY/HTTP_PROXY where corporate proxies are mandatory
- Trust interception CAs via SSL_CERT_FILE/REQUESTS_CA_BUNDLE for httpx
- Distinguish by prefix: 'Error fetching file' = transport; 'Failed to fetch file' = HTTP status
When it happens
Trigger: K8s pod without egress to api.bitbucket.org (network policy/air-gapped cluster); corporate proxy required but HTTP_PROXY/HTTPS_PROXY unset; TLS-intercepting middlebox with an untrusted CA making verification fail; self-hosted base_url unreachable; IPv6/DNS misconfiguration.
Common situations: Services moved into a restricted network segment; certificates rotated on the interception proxy; CI runners behind NAT with flaky DNS; local dev on VPN split-tunnel that drops the API host.
Related errors
- Cisco AI Defense API request failed
- Failed to fetch OIDC UserInfo
- DNS resolution failed for
- Error getting file metadata for
- Error listing files in
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/cc4731c261e79254.
Report an issue: GitHub.
Appendix: source
Thrown at litellm/integrations/bitbucket/bitbucket_client.py:118
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:
response: Final = self.http_handler.get(url, headers=self.headers)
response.raise_for_status()View on GitHub (pinned to 77b7c6c40c)