BerriAI/litellm · error · Exception
Failed to get file metadata for
Error message
Failed to get file metadata for '{file_path}': {e} What it means
Raised by BitBucketClient.get_file_metadata when the ranged GET for a file (Range: bytes=0-0) fails with an HTTP status error other than 404 — 404 is converted to a None return. So this fires on 401 (authentication failed), 403 (token lacks read scope for the path), 429 (rate limit), and 5xx responses from the BitBucket API.
Solutions
- Remember None means 'not found' — only non-404 failures raise, so treat this as an auth/capacity problem
- Verify the token still authenticates: curl -H "Authorization: Bearer $TOKEN" "https://api.bitbucket.org/2.0/user"
- Confirm the token has repository read scope for workspace/repository
- Retry with exponential backoff for 429/5xx wrapped causes
Defensive patterns
Strategy: try-catch
Validate before calling
# None return is the built-in 404 path; pre-check relevance of the token instead
import httpx, os
def token_valid() -> bool:
try:
r = httpx.get("https://api.bitbucket.org/2.0/user",
headers={"Authorization": f"Bearer {os.getenv('BITBUCKET_ACCESS_TOKEN','')}"},
timeout=5)
return r.status_code == 200
except httpx.RequestError:
return False Try / catch
try:
meta = client.get_file_metadata(path)
except Exception as e:
if "401" in str(e) or "Authentication" in str(e):
... # refresh token
else:
... # rate limit / 5xx: retry with backoff
else:
if meta is None:
... # file genuinely absent (404 path) Prevention
- Remember the contract: None means not-found; only non-404 failures raise
- Keep the token's read scope aligned with the repos being polled
- Rate-limit metadata polling loops to avoid 429s
When it happens
Trigger: Calling get_file_metadata for a file in a repo the token cannot read (403), with an expired access token (401), during BitBucket API rate limiting (429), or during a BitBucket-side incident (5xx). The path has already passed _sanitize_file_path, so traversal/URL-special-character mistakes raise ValueError earlier.
Common situations: Pre-checking that a .prompt file exists before loading it; tokens with only write-but-not-read scopes; heavy polling loops hitting rate limits; tokens revoked mid-session.
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 get branches
- Failed to get repository info
- Authentication failed. Check your BitBucket access token…
- Error getting file metadata for
- Error listing files in
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/44d8ed53cd779346.
Report an issue: GitHub.
Appendix: source
Thrown at litellm/integrations/bitbucket/bitbucket_client.py:243
try:
# Use GET with Range header to get just the headers (HEAD equivalent)
headers: Final = self.headers.copy()
headers["Range"] = "bytes=0-0" # Request only first byte to get headers
response: Final = self.http_handler.get(url, headers=headers)
response.raise_for_status()
return {
"content_type": response.headers.get("content-type"),
"content_length": response.headers.get("content-length"),
"last_modified": response.headers.get("last-modified"),
}
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
raise Exception(f"Failed to get file metadata for '{file_path}': {e}")
else:
raise Exception(f"Error getting file metadata for '{file_path}': {e}")
def close(self):
"""Close the HTTP handler to free resources."""
if hasattr(self, "http_handler"):
self.http_handler.close()
View on GitHub (pinned to 77b7c6c40c)