{"record":{"id":"af106d4bd8fa1a6f","repo":"BerriAI/litellm","slug":"failed-to-list-files-in-directory-path-e","errorCode":null,"errorMessage":"Failed to list files in '{directory_path}': {e}","messagePattern":"Failed to list files in '(.+?)': (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"litellm/integrations/bitbucket/bitbucket_client.py","lineNumber":161,"sourceCode":"                    file_path = item.get(\"path\", \"\")\n                    if file_path.endswith(file_extension):\n                        files.append(file_path)\n\n            return files\n\n        except Exception as e:\n            # Check if it's an HTTP error\n            if hasattr(e, \"response\") and hasattr(e.response, \"status_code\"):\n                if e.response.status_code == 404:\n                    return []\n                elif e.response.status_code == 403:\n                    raise Exception(\n                        f\"Access denied to directory '{directory_path}'. Check your BitBucket permissions for workspace '{self.workspace}' and repository '{self.repository}'.\"\n                    )\n                elif e.response.status_code == 401:\n                    raise Exception(\"Authentication failed. Check your BitBucket access token and permissions.\")\n                else:\n                    raise Exception(f\"Failed to list files in '{directory_path}': {e}\")\n            else:\n                raise Exception(f\"Error listing files in '{directory_path}': {e}\")\n\n    def get_repository_info(self) -> dict[str, Any]:\n        \"\"\"\n        Get information about the repository.\n\n        Returns:\n            Dictionary containing repository information\n        \"\"\"\n        url: Final = f\"{self.base_url}/repositories/{self.workspace}/{self.repository}\"\n\n        try:\n            response: Final = self.http_handler.get(url, headers=self.headers)\n            response.raise_for_status()\n            return response.json()\n        except Exception as e:\n            raise Exception(f\"Failed to get repository info: {e}\")","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/integrations/bitbucket/bitbucket_client.py#L143-L179","documentation":"Raised by BitBucketClient.list_files_in_directory when the BitBucket src endpoint returns any HTTP status other than 401/403/404 (e.g. 500, 502, 429 rate-limit). The original requests exception is stringified into the message, so the status code and URL are visible in text but the exception type and response object are lost. It is a catch-all re-raise after the specific status codes were already handled.","triggerScenarios":"BitBucket API rate limiting (429) from aggressive polling of list_files_in_directory, BitBucket server errors (5xx), a branch name that triggers a redirect, or a workspace/repository name with typos producing unexpected 4xx codes not in the handled set.","commonSituations":"Prompt-manager loops that list a prompts directory on every request and hit rate limits; BitBucket Cloud incidents; enterprise BitBucket Server deployments where the API path shape differs and base_url was overridden.","solutions":["Read the embedded status code in the message text; for 429 add backoff/retry with exponential delays around list_files_in_directory","Cache directory listings instead of listing on every prompt lookup","If pointing at BitBucket Server/Data Center, verify base_url includes the /rest/api/2.0-style path your instance expects","Check https://status.atlassian.com for active BitBucket Cloud incidents if the status is 5xx"],"exampleFix":"# before\nfiles = client.list_files_in_directory(\"prompts\")\n\n# after (retry with backoff)\nimport time\nfor attempt in range(5):\n    try:\n        files = client.list_files_in_directory(\"prompts\")\n        break\n    except Exception as e:\n        if \"429\" in str(e) and attempt < 4:\n            time.sleep(2 ** attempt)\n            continue\n        raise","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"import time\n\nfor attempt in range(5):\n    try:\n        files = client.list_files_in_directory(\"prompts\")\n        break\n    except Exception as e:\n        msg = str(e)\n        if (\"429\" in msg or \"5\" in msg.split(\" \")[0]) and attempt < 4:\n            time.sleep(2 ** attempt)\n            continue\n        raise","preventionTips":["Cache directory listings with a TTL instead of listing per request","Stay under BitBucket Cloud's anonymous/authenticated rate limits by batching work","Log the full message — it embeds the HTTP status for triage"],"tags":["bitbucket","http-error","rate-limit","retry"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}