BerriAI/litellm · error · Exception

Access denied to file '{file_path}'. Check your BitBucket pe

Error message

Access denied to file '{file_path}'. Check your BitBucket permissions for workspace '{self.workspace}' and repository '{self.repository}'.

What it means

Raised by BitBucketClient.get_file when the BitBucket API responds 403 to the raw-file fetch. The client's except block inspects the exception for a .response.status_code; 403 means authentication succeeded but the principal lacks read permission on that file/repo. 404 is deliberately mapped to None (file-not-found), so a 403 genuinely means access denial.

Source

Thrown at litellm/integrations/bitbucket/bitbucket_client.py:110

            response.raise_for_status()

            # BitBucket returns file content as base64 encoded
            if response.headers.get("content-type", "").startswith("text/"):
                return response.text
            else:
                # For binary files or when content-type is not text, try to decode as base64
                try:
                    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:

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Verify workspace and repository values resolve to the intended repo (open https://bitbucket.org/<workspace>/<repository>)
  2. Recreate the app password / token with the repository:read scope (or full public/private repo read for private repos)
  3. Confirm the account can view the file in the BitBucket UI while logged in as the token owner
  4. Check that the branch configured exists and is readable (default is 'main')

Example fix

# before
config = {"workspace": "my-workspace", "repository": "my-repo", "access_token": account_only_token}

# after
# app password with Repository access: Read enabled
config = {"workspace": "my-workspace", "repository": "my-repo", "access_token": repo_read_token}
Defensive patterns

Strategy: try-catch

Validate before calling

import httpx

def can_read_file(workspace: str, repo: str, path: str, token: str, branch: str = "main") -> bool:
    url = f"https://api.bitbucket.org/2.0/repositories/{workspace}/{repo}/src/{branch}/{path}"
    r = httpx.get(url, auth=("x-token-auth", token), timeout=10)
    return r.status_code == 200  # 403 = no permission, 404 = missing

Try / catch

try:
    content = client.get_file(path)
except Exception as e:
    msg = str(e)
    if "Access denied" in msg:
        raise PermissionError(f"token lacks read access to {path}; check repo scopes") from e
    raise

Prevention

When it happens

Trigger: App password/token scoped to a workspace the repository does not belong to; token without 'repository read' scope; repository or workspace name typo that resolves to a repo you cannot see; branch not accessible with the token's permissions.

Common situations: App password created with only account scopes and no repository scopes; workspace-repo mismatch (right repo name in the wrong workspace); recently rotated token with narrower scopes; team-based access control restricting the directory.

Understand the failure class

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/b1de80c3c88a7cd3. Report an issue: GitHub.