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

  1. 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.
  2. 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.
  3. 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

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


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/5cdcbc6bd31d37f5. Report an issue: GitHub.