BerriAI/litellm · error · Exception
Access denied to directory '{directory_path}'. Check your Gi
Error message
Access denied to directory '{directory_path}'. Check your GitLab permissions for project '{self.project}'. What it means
GitLab answered 403 Forbidden for the repository tree API used by list_files (GET /projects/<id>/repository/tree?ref=...). The token authenticated but cannot read this project/directory: role below Reporter on a private project, missing read_repository scope, or a path under a repo the identity cannot see. Note that a 404 returns an empty list instead of raising, so this error specifically means the identity is being denied, not that the path is missing.
Source
Thrown at litellm/integrations/gitlab/gitlab_client.py:225
if resp.status_code == 404:
return []
resp.raise_for_status()
data: Final = resp.json() or []
files: Final[list[str]] = []
for item in data:
if item.get("type") == "blob":
file_path = item.get("path", "")
if not file_extension or file_path.endswith(file_extension):
files.append(file_path)
return files
except Exception as e:
status: Final = getattr(getattr(e, "response", None), "status_code", None)
if status == 404:
return []
if status == 403:
raise Exception(
f"Access denied to directory '{directory_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 list files in '{directory_path}': {e}")
def get_repository_info(self) -> dict[str, Any]:
"""Get information about the project/repository."""
url: Final = f"{self.base_url}/projects/{self._project_enc}"
try:
resp: Final = self.http_handler.get(url, headers=self.headers)
resp.raise_for_status()
return resp.json()
except Exception as e:
raise Exception(f"Failed to get repository info: {e}")
def test_connection(self) -> bool:
"""Test the connection to the GitLab project."""View on GitHub (pinned to 77b7c6c40c)
Solutions
- Confirm the token's user can browse that directory in the GitLab UI
- Use read_repository scope and Reporter+ role on the project
- Check the directory path spelling/case and that it lives in the configured project
- Verify you pointed at the right project (a wrong project that exists and is private yields 403)
Example fix
# before: token without repository read on a private project
files = client.list_files("prompts/internal")
# after: token with read_repository scope and a path the identity can see
files = client.list_files("prompts") Defensive patterns
Strategy: try-catch
Validate before calling
# Fail fast at startup instead of discovering 403s during prompt listing
if not client.test_connection():
raise RuntimeError("GitLab credentials/project invalid")
client.list_files("prompts") # exercises the tree API at boot Try / catch
try:
files = client.list_files("prompts")
except Exception as e:
if "Access denied to directory" in str(e):
raise RuntimeError(
"Token cannot list the prompts directory - "
"grant read_repository / Reporter+ or fix the path"
) from e
raise Prevention
- Exercise the tree listing once during deployment as a permission check
- Keep prompts in one directory the integration token can read
- Review scopes after every GitLab token rotation
When it happens
Trigger: list_files('prompts') with a Guest-role token; PAT without read_repository scope; directory path belonging to a different (private) subgroup repo; protected ref with an unprivileged token.
Common situations: Startup prompt discovery running with a least-privilege CI token; org restructures moving repositories between groups; scope changes after token rotation.
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 GitLab permi
- Access denied to prompt version '{prompt_version_id}'. Check
- Access denied to file '{file_path}'. Check your BitBucket pe
- Access denied to directory '{directory_path}'. Check your Bi
- Failed to list files in '{directory_path}': {e}
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/a354fdb04254facf.
Report an issue: GitHub.