{"record":{"id":"cc4731c261e79254","repo":"BerriAI/litellm","slug":"error-fetching-file-file-path-e","errorCode":null,"errorMessage":"Error fetching file '{file_path}': {e}","messagePattern":"Error fetching file '(.+?)': (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"litellm/integrations/bitbucket/bitbucket_client.py","lineNumber":118,"sourceCode":"                    return base64.b64decode(response.content).decode(\"utf-8\")\n                except Exception:\n                    return response.text\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 None\n                elif e.response.status_code == 403:\n                    raise Exception(\n                        f\"Access denied to file '{file_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 fetch file '{file_path}': {e}\")\n            else:\n                raise Exception(f\"Error fetching file '{file_path}': {e}\")\n\n    def list_files(self, directory_path: str = \"\", file_extension: str = \".prompt\") -> list[str]:\n        \"\"\"\n        List files in a directory with a specific extension.\n\n        Args:\n            directory_path: Directory path in the repository (empty for root)\n            file_extension: File extension to filter by (default: .prompt)\n\n        Returns:\n            List of file paths\n        \"\"\"\n        safe_dir: Final = _sanitize_file_path(directory_path) if directory_path else \"\"\n        url: Final = f\"{self.base_url}/repositories/{self.workspace}/{self.repository}/src/{self.branch}/{safe_dir}\"\n\n        try:\n            response: Final = self.http_handler.get(url, headers=self.headers)\n            response.raise_for_status()","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/integrations/bitbucket/bitbucket_client.py#L100-L136","documentation":"The non-HTTP branch of get_file's error handling: the caught exception had no .response attribute (or .response lacked status_code), so it was not an HTTP-layer error from the HTTPHandler. The exception is wrapped in a generic Exception with the file path. Typical sources are DNS resolution failures, connection refused/timeout, TLS errors, or bugs in response processing — i.e. the request likely never reached BitBucket or failed below HTTP.","triggerScenarios":"No network egress from the container (DNS failure for api.bitbucket.org); corporate proxy required but httpx handler not configured to use it; TLS certificate interception breaking the handshake; self.base_url customized to an unreachable value.","commonSituations":"Running litellm in an air-gapped or egress-restricted cluster; proxy env vars (HTTPS_PROXY) not passed into the container; base_url typo introduced when overriding the default https://api.bitbucket.org/2.0.","solutions":["Read the embedded '{e}' text — DNS/connect/SSL errors name the actual failure","Verify egress: curl https://api.bitbucket.org/2.0 from the same container/pod","Set HTTPS_PROXY/HTTP_PROXY (and pass them into the deployment) if a corporate proxy is required","If base_url was overridden, revert to https://api.bitbucket.org/2.0 or fix the typo"],"exampleFix":"# before\n# pod has no egress -> Exception: Error fetching file 'prompts/x.prompt': [Errno -2] Name or service not known\n\n# after\n# allow egress / set proxy in the container spec\nenv:\n  - name: HTTPS_PROXY\n    value: http://proxy.corp.example:3128","handlingStrategy":"try-catch","validationCode":"import socket\n\ndef can_resolve_bitbucket() -> bool:\n    try:\n        socket.getaddrinfo(\"api.bitbucket.org\", 443)\n        return True\n    except socket.gaierror:\n        return False\n\nassert can_resolve_bitbucket(), \"no DNS egress to api.bitbucket.org\"","typeGuard":null,"tryCatchPattern":"try:\n    content = client.get_file(path)\nexcept Exception as e:\n    msg = str(e).lower()\n    if any(k in msg for k in (\"name or service not known\", \"connect\", \"ssl\", \"proxy\")):\n        raise NetworkError(\"cannot reach api.bitbucket.org — check egress/proxy config\") from e\n    raise","preventionTips":["Verify HTTPS egress (DNS + firewall) from the runtime container before deploying","Propagate HTTPS_PROXY/HTTP_PROXY into containers that require a corporate proxy","Cache prompts locally so a network outage does not break every request","Do not override base_url unless you operate a BitBucket mirror that is actually reachable"],"tags":["bitbucket","network","connectivity","exception-wrapping"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}