BerriAI/litellm · error · Exception
Access denied to file '{file_path}'. Check your GitLab permi
Error message
Access denied to file '{file_path}'. Check your GitLab permissions for project '{self.project}'. What it means
Raised by GitLabClient._get_file_content_via_raw when the GitLab raw-file API returns HTTP 403: the token is valid and authenticated, but the authenticated identity lacks permission to read the repository/file — e.g. a project without Guest+ access, a private repo with an outsider token, or IP restrictions/robot bans on the raw endpoint. The status is extracted from the httpx exception's .response.status_code.
Source
Thrown at litellm/integrations/gitlab/gitlab_client.py:145
if resp.status_code == 404:
# Fallback to JSON endpoint
return self._get_file_content_via_json(file_path, ref=ref)
resp.raise_for_status()
ctype: Final = (resp.headers.get("content-type") or "").lower()
if ctype.startswith("text/") or "charset=" in ctype or ctype.startswith("application/json"):
return resp.text
try:
return resp.content.decode("utf-8")
except Exception:
return resp.content.decode("utf-8", errors="replace")
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}': {e}")
def _get_file_content_via_json(self, file_path: str, *, ref: str | None = None) -> str | None:
"""
Fallback for get_file_content(): use the JSON file API which returns base64 content.
"""
json_url: Final = self._file_json_url(file_path, ref=ref)
try:
resp: Final = self.http_handler.get(json_url, headers=self.headers)
if resp.status_code == 404:
return None
resp.raise_for_status()
data: Final = resp.json()
content: Final = data.get("content")View on GitHub (pinned to 6c2dcb801b)
Solutions
- Verify the token's identity has at least Reporter read access to the project: curl -H 'Private-Token: <token>' 'https://gitlab.com/api/v4/projects/<id>/repository/files/<path>?ref=main'.
- If using auth_method oauth, confirm the OAuth token has read_repository scope and Bearer auth is intended.
- Ask the admin to enable the raw endpoint or stop blocking it for API clients if the 403 comes from endpoint restrictions.
- Point to a project the token can access or mint a project access token for that repo.
Defensive patterns
Strategy: try-catch
Validate before calling
import httpx, urllib.parse
def can_read_project_file(base_url: str, project: str, file_path: str, ref: str, token: str) -> None:
enc = urllib.parse.quote(project, safe="")
fpath = urllib.parse.quote(file_path, safe="")
resp = httpx.get(
f"{base_url}/projects/{enc}/repository/files/{fpath}/raw",
params={"ref": ref},
headers={"Private-Token": token},
timeout=10,
)
if resp.status_code == 403:
raise PermissionError("Token cannot read this project/file — grant Reporter+ access")
resp.raise_for_status() Try / catch
try:
content = client.get_file_content("chat/greet.prompt")
except Exception as e:
if "Access denied" in str(e):
raise PermissionError(f"GitLab token lacks read access: {e}") from e
raise Prevention
- Run an access smoke-test per project at deploy time using the same token.
- Prefer project access tokens scoped to the prompt repo over broad personal tokens.
- Track token scopes and project membership in your secrets-management runbook.
When it happens
Trigger: get_file_content() on a private project with a token whose owner is not a member; using a group access token scoped to a different group; GitLab rate-limiting or blocking the raw endpoint (raw endpoints can be disabled by admins); requesting a file in a protected branch the identity cannot read.
Common situations: Shared CI tokens that work for one group but not another; personal access tokens with scopes like api only vs read_api on restricted projects; self-managed GitLab instances where the raw endpoint is behind additional ACLs; prompt repos recently switched to private without re-issuing tokens.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Access denied to file '{file_path}'. Check your BitBucket pe
- Access denied to directory '{directory_path}'. Check your Bi
- GCS upload failed: status={response.status_code} body={respo
- Failed to fetch file '{file_path}': {e}
- Failed to fetch file '{file_path}' via JSON endpoint: {e}
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/612ff51723deee1e.
Report an issue: GitHub.