{"record":{"id":"7959d86c84ac9fed","repo":"BerriAI/litellm","slug":"error-listing-files-in-directory-path-e","errorCode":null,"errorMessage":"Error listing files in '{directory_path}': {e}","messagePattern":"Error listing files in '(.+?)': (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"litellm/integrations/bitbucket/bitbucket_client.py","lineNumber":163,"sourceCode":"                        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}\")\n\n    def test_connection(self) -> bool:","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/integrations/bitbucket/bitbucket_client.py#L145-L181","documentation":"Raised by BitBucketClient.list_files when the GET to /repositories/{workspace}/{repository}/src/{branch}/{directory} fails with an exception that carries no HTTP status code, i.e. the request never produced an HTTP response. The sibling branches handle 404 (returns []), 403, 401, and other HTTP status errors, so this else-branch catches connection-level failures and response-decoding failures. The original exception text is appended to the message.","triggerScenarios":"Calling list_files (directly, or via the BitBucket prompt manager loading all .prompt files at startup) when DNS for api.bitbucket.org fails, the TCP connection is refused or times out (firewall/proxy blocking egress), TLS verification fails (corporate SSL inspection, missing CA bundle), or response.json() raises because a proxy returned an HTML error page instead of JSON. Also triggered by a custom base_url pointing at a wrong host/port.","commonSituations":"Corporate networks with SSL-inspecting proxies, misconfigured HTTP_PROXY/HTTPS_PROXY env vars, self-hosted BitBucket Data Center URL typos in the client config dict, transient outages while the LiteLLM proxy boots, and IPv6 resolution problems in containers.","solutions":["From the same host, curl the exact URL to confirm reachability: curl -H \"Authorization: Bearer $TOKEN\" \"https://api.bitbucket.org/2.0/repositories/<ws>/<repo>/src/main/\"","Verify the base_url in the BitBucket config dict (default https://api.bitbucket.org/2.0) and fix typos in host/port","Check proxy env vars and CA bundles (HTTPS_PROXY, SSL_CERT_FILE, REQUESTS_CA_BUNDLE) if running behind a corporate proxy","Add retry/backoff around prompt-manager initialization for transient network failures"],"exampleFix":"// before\nfiles = bitbucket_client.list_files(\"prompts\")\n\n// after\nimport time\nfor attempt in range(3):\n    try:\n        files = bitbucket_client.list_files(\"prompts\")\n        break\n    except Exception as e:\n        if attempt == 2 or not str(e).startswith(\"Error listing files\"):\n            raise\n        time.sleep(2 ** attempt)","handlingStrategy":"try-catch","validationCode":"import httpx, os\n\ndef bitbucket_reachable(base_url: str = \"https://api.bitbucket.org/2.0\",\n                        token: str | None = None) -> bool:\n    token = token or os.getenv(\"BITBUCKET_ACCESS_TOKEN\", \"\")\n    try:\n        httpx.get(base_url, headers={\"Authorization\": f\"Bearer {token}\"}, timeout=5.0)\n        return True\n    except httpx.RequestError:\n        return False","typeGuard":null,"tryCatchPattern":"try:\n    files = client.list_files(directory)\nexcept Exception as e:\n    msg = str(e)\n    if msg.startswith(\"Access denied\"):\n        ...  # permission problem\n    elif msg.startswith(\"Authentication failed\"):\n        ...  # credential problem\n    elif msg.startswith(\"Error listing files\"):\n        ...  # network-level failure: check DNS/proxy/TLS, retry with backoff\n    else:\n        raise","preventionTips":["Run a connectivity smoke test to api.bitbucket.org during deployment before enabling BitBucket prompt loading","Keep proxy env vars (HTTPS_PROXY, NO_PROXY) and CA bundles correctly configured in containers","Wrap prompt-manager initialization in retry with exponential backoff for transient network errors","Prefer test_connection() for health checks instead of parsing wrapped exceptions"],"tags":["bitbucket","network","http","file-listing","litellm-prompts"],"backgroundTag":"network-connectivity-error","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}