BerriAI/litellm · warning · ValueError
Invalid file path {file_path!r}: contains URL special charac
Error message
Invalid file path {file_path!r}: contains URL special characters What it means
A deliberate security guard in _sanitize_file_path: before URL-encoding path segments for the BitBucket raw-file API, the function rejects any file path containing '#' or '?'. Those characters have special meaning in URLs and could otherwise alter the request target (e.g. truncate the path at a fragment or inject query params), so they are treated as invalid input rather than escaped.
Source
Thrown at litellm/integrations/bitbucket/bitbucket_client.py:15
"""
BitBucket API client for fetching .prompt files from BitBucket repositories.
"""
import base64
import urllib.parse
from typing import Any, Final
from litellm.llms.custom_httpx.http_handler import HTTPHandler
def _sanitize_file_path(file_path: str) -> str:
"""Reject path traversal and URL-encode each path segment."""
if "#" in file_path or "?" in file_path:
raise ValueError(f"Invalid file path {file_path!r}: contains URL special characters")
parts: Final = file_path.split("/")
for part in parts:
if part == "..":
raise ValueError(f"Invalid file path {file_path!r}: path traversal detected")
return "/".join(urllib.parse.quote(part, safe="") for part in parts)
class BitBucketClient:
"""
Client for interacting with BitBucket API to fetch .prompt files.
Supports:
- Authentication with access tokens
- Fetching file contents from repositories
- Team-based access control through BitBucket permissions
- Branch-specific file fetching
"""
View on GitHub (pinned to 6c2dcb801b)
Solutions
- Remove '#' and '?' from the file path / prompt_id used to address the file
- Rename the repository file if it actually contains those characters
- Sanitize external input before passing it as a path (strip fragments/queries at your API boundary)
Example fix
# before
content = client.get_file("prompts/summarize#latest.prompt") # ValueError
# after
content = client.get_file("prompts/summarize-latest.prompt") Defensive patterns
Strategy: validation
Validate before calling
def validate_file_path(file_path: str) -> str:
if "#" in file_path or "?" in file_path:
raise ValueError(f"path must not contain '#' or '?': {file_path!r}")
return file_path
path = validate_file_path(user_supplied_path)
content = client.get_file(path) Type guard
def is_safe_prompt_path(p: str | None) -> bool:
if not isinstance(p, str) or not p:
return False
return "#" not in p and "?" not in p and ".." not in p.split("/") and p.endswith(".prompt") Try / catch
try:
client.get_file(path)
except ValueError as e:
if "URL special characters" in str(e):
path = path.split("#")[0].split("?")[0] # or reject input outright
raise ValueError("reject user paths containing fragments/queries") from e
raise Prevention
- Strip URL fragments and query strings from any path derived from URLs or user input before passing to the client
- Restrict prompt paths to an allow-listed directory prefix and .prompt extension
- Never build API paths by concatenating raw user input
When it happens
Trigger: Calling get_file (directly or via the BitBucket prompt manager) with a file path containing '#' or '?', e.g. 'prompts/summarize#v2.prompt' or 'faq/q?a.prompt'; user-supplied prompt paths passed through without sanitization; prompt_id strings copied from URLs that include fragments.
Common situations: Prompt IDs derived from URLs or user input containing anchors/query strings; files genuinely named with '#' or '?' (must be renamed — the guard is unconditional); testing the integration with hand-crafted paths.
Related errors
- Invalid file path {file_path!r}: path traversal detected
- Only admins or team admins can update projects
- Cannot reassign project to a team you are not an admin of
- bitbucket_config is required for BitBucket prompt integratio
- workspace, repository, and access_token are required
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/e6b6c8e6ba91048c.
Report an issue: GitHub.