BerriAI/litellm · error · ValueError
{field_name} cannot be a dot path segment
Error message
{field_name} cannot be a dot path segment What it means
Thrown by encode_url_path_segment when the value is exactly "." or "..". urllib.parse.quote(..., safe="") deliberately leaves RFC 3986 unreserved characters like '.' unescaped, so a literal dot segment would survive encoding and later be path-normalized by the HTTP client — enabling path traversal (e.g. escaping an intended URL prefix). litellm rejects dot segments outright as part of its SSRF/path-traversal hardening.
Source
Thrown at litellm/litellm_core_utils/url_utils.py:62
"""Raised when a URL targets a blocked network."""
def encode_url_path_segment(value: Any, *, field_name: str = "path parameter") -> str:
"""Percent-encode one user-controlled URL path segment.
``urllib.parse.quote(..., safe="")`` intentionally leaves RFC 3986
unreserved characters such as ``.`` unescaped, so reject standalone dot
segments before they can be appended to an upstream URL and normalized by
the HTTP client.
"""
if value is None:
raise ValueError(f"{field_name} is required")
value_str: Final = str(value)
if value_str == "":
raise ValueError(f"{field_name} is required")
if value_str in {".", ".."}:
raise ValueError(f"{field_name} cannot be a dot path segment")
return quote(value_str, safe="")
def encode_url_path_segments(value: Any, *, field_name: str = "path") -> str:
"""Percent-encode a user-controlled URL path made of multiple segments.
Empty segments are rejected, so leading, trailing, or consecutive slashes
fail closed instead of being normalized by the HTTP client.
"""
if value is None:
raise ValueError(f"{field_name} is required")
value_str: Final = str(value)
if value_str == "":
raise ValueError(f"{field_name} is required")
encoded_segments: Final = []View on GitHub (pinned to 6c2dcb801b)
Solutions
- Reject or sanitize user-supplied path components before URL construction: allow only a safe charset (e.g. [A-Za-z0-9_-]+) for ids destined for path segments.
- If traversal-style keys are legitimate, percent-encode the slashes and dots yourself at a higher layer or pass the key as a query parameter instead.
- Return a 400 to the client naming the invalid field instead of letting the ValueError propagate.
Example fix
# before
url = f"{base}/files/{encode_url_path_segment(file_id, field_name='file_id')}"
# after
import re
if not re.fullmatch(r"[A-Za-z0-9_-]+", file_id or ""):
raise HTTPException(400, "file_id contains illegal characters")
url = f"{base}/files/{encode_url_path_segment(file_id, field_name='file_id')}" Defensive patterns
Strategy: validation
Validate before calling
import re
def is_safe_path_segment(value) -> bool:
return bool(isinstance(value, str) and re.fullmatch(r"[^/\\]+", value) and value not in {".", ".."}) Type guard
def is_safe_path_segment(value) -> bool:
return isinstance(value, str) and value not in {"", ".", ".."} and "/" not in value Try / catch
try:
encoded = encode_url_path_segment(value, field_name="file_id")
except ValueError:
return bad_request("file_id contains illegal path characters") Prevention
- Allowlist a charset (e.g. [A-Za-z0-9_-]) for user-supplied URL path components.
- Treat dot-segment rejection as expected behavior and map it to a 400, not a 500.
- Never assemble URLs by string concatenation of raw user input; always go through the encoder.
When it happens
Trigger: Passing a user-controlled id/name that equals "." or ".." into a URL path builder — e.g. encode_url_path_segment("..", field_name="file_id"), or an encode_url_path_segments("files/../admin") call where one split segment is a dot segment.
Common situations: Path traversal attempts or fuzzed input reaching a URL-building layer; file/blob id fields that accept arbitrary strings; copying S3-style key paths into segment builders without validating each component.
Related errors
- URL scheme '{parsed.scheme}' is not allowed
- Invalid file path {file_path!r}: path traversal detected
- MAVVRIK_API_ENDPOINT host must be a Mavvrik domain (e.g. htt
- Mavvrik FOCUS destination: {label} must be a GCS endpoint (s
- URL has no hostname
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/5cdcbc6bd31d37f5.
Report an issue: GitHub.